<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
	<id>https://www.glc.us.es/~jalonso/LMF2019/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jalonso</id>
	<title>Lógica matemática y fundamentos (2018-19) - Contribuciones del usuario [es]</title>
	<link rel="self" type="application/atom+xml" href="https://www.glc.us.es/~jalonso/LMF2019/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jalonso"/>
	<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php/Especial:Contribuciones/Jalonso"/>
	<updated>2026-07-17T22:25:08Z</updated>
	<subtitle>Contribuciones del usuario</subtitle>
	<generator>MediaWiki 1.31.14</generator>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Definiciones_inductivas&amp;diff=828</id>
		<title>Definiciones inductivas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Definiciones_inductivas&amp;diff=828"/>
		<updated>2020-05-27T18:21:51Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 9: Definiciones inductivas›&lt;br /&gt;
&lt;br /&gt;
theory T9_Definiciones_inductivas&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section ‹El conjunto de los números pares›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  · El conjunto de los números pares se define inductivamente como el&lt;br /&gt;
    menor conjunto que contiene al 0 y es cerrado por la operación (+2).&lt;br /&gt;
&lt;br /&gt;
  · El conjunto de los números pares también puede definirse como los &lt;br /&gt;
    naturales divisible por 2.&lt;br /&gt;
&lt;br /&gt;
  · Veremos cómo se escriben las dos definiciones en Isabelle/HOL y cómo&lt;br /&gt;
    se demuestra su equivalencia.›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Definición inductiva del conjunto de los pares›&lt;br /&gt;
&lt;br /&gt;
inductive_set par :: &amp;quot;nat set&amp;quot; where&lt;br /&gt;
  cero [intro!]: &amp;quot;0 ∈ par&amp;quot; &lt;br /&gt;
| paso [intro!]: &amp;quot;n ∈ par ⟹ (Suc (Suc n)) ∈ par&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  · Una definición inductiva está formada con reglas de introducción.&lt;br /&gt;
&lt;br /&gt;
  · La definición inductiva genera varios teoremas:&lt;br /&gt;
    · par.cero:   0 ∈ par&lt;br /&gt;
    · par.paso:   n ∈ par ⟹ Suc (Suc n) ∈ par&lt;br /&gt;
    · par.simps:  (a ∈ par) = (a = 0 ∨ (∃n. a = Suc (Suc n) ∧ n ∈ par))&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm par.cero&lt;br /&gt;
thm par.paso&lt;br /&gt;
thm par.simps&lt;br /&gt;
&lt;br /&gt;
subsection ‹Uso de las reglas de introducción›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Lema: Los números de la forma 2*k son pares.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma dobles_son_pares [intro!]: &lt;br /&gt;
  &amp;quot;2*k ∈ par&amp;quot;&lt;br /&gt;
  apply (induct k) &lt;br /&gt;
     (* 1. 2 * 0 ∈ par&lt;br /&gt;
        2. ⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma dobles_son_pares_2: &lt;br /&gt;
  &amp;quot;2*k ∈ par&amp;quot;&lt;br /&gt;
  by (induct k) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma dobles_son_pares_3:&lt;br /&gt;
  &amp;quot;2*k ∈ par&amp;quot;&lt;br /&gt;
proof (induct k)&lt;br /&gt;
  show &amp;quot;2 * 0 ∈ par&amp;quot; &lt;br /&gt;
    by auto&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par&amp;quot; &lt;br /&gt;
    by auto&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  · Nota: Nuestro objetivo es demostrar la equivalencia de la definición&lt;br /&gt;
    anterior y la definición mediante divisibilidad (even).&lt;br /&gt;
  &lt;br /&gt;
  · Lema: Si n es divisible por 2, entonces es par.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
lemma even_imp_par: &amp;quot;even n ⟹ n ∈ par&amp;quot; &lt;br /&gt;
  using dobles_son_pares_3 by blast&lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla de inducción› &lt;br /&gt;
&lt;br /&gt;
text ‹Entre las reglas generadas por la definión de par está la de&lt;br /&gt;
  inducción:&lt;br /&gt;
  · par.induct: ⟦ x ∈ par; &lt;br /&gt;
                 P 0; &lt;br /&gt;
                 ⋀n. ⟦n ∈ par; P n⟧ ⟹ P (Suc (Suc n))⟧ &lt;br /&gt;
                ⟹ P x&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm par.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Lema: Los números pares son divisibles por 2.› &lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma par_imp_even: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
  apply (induction rule: par.induct)&lt;br /&gt;
     (* 1. even 0&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply (simp only: dvd_def)&lt;br /&gt;
     (* 1. ∃k. 0 = 2 * k&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply (rule_tac x=0 in exI)&lt;br /&gt;
     (* 1. 0 = 2 * 0&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply simp&lt;br /&gt;
     (* ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
  apply (simp only: dvd_def)&lt;br /&gt;
     (* ⋀n. ⟦n ∈ par; ∃k. n = 2 * k⟧ ⟹ ∃k. Suc (Suc n) = 2 * k *)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
     (* ⋀n k. ⟦n ∈ par; n = 2 * k⟧ ⟹ ∃k. Suc (Suc n) = 2 * k*)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;k+1&amp;quot; in exI)&lt;br /&gt;
     (* ⋀n k. ⟦n ∈ par; n = 2 * k⟧ ⟹ Suc (Suc n) = 2 * (k + 1) *)&lt;br /&gt;
  apply simp&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración aplicativa›&lt;br /&gt;
lemma par_imp_even_2: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
  apply (induction rule: par.induct)&lt;br /&gt;
     (* 1. even 0&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma par_imp_even_3: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
  by (induction rule: par.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma par_imp_even_4: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
proof (induction rule: par.induct)&lt;br /&gt;
  show &amp;quot;even 0&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n :: nat&lt;br /&gt;
  assume H1: &amp;quot;n ∈ par&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even n&amp;quot;&lt;br /&gt;
  have &amp;quot;∃k. n = 2*k&amp;quot; &lt;br /&gt;
    using H2 by (simp add: dvd_def)&lt;br /&gt;
  then obtain k where &amp;quot;n = 2*k&amp;quot; &lt;br /&gt;
    by (rule exE)&lt;br /&gt;
  then have &amp;quot;Suc (Suc n) = 2*(k+1)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  then have &amp;quot;∃k. Suc (Suc n) = 2*k&amp;quot; &lt;br /&gt;
    by (rule exI)&lt;br /&gt;
  then show &amp;quot;even (Suc (Suc n))&amp;quot; &lt;br /&gt;
    by (simp add: dvd_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración declarativa›&lt;br /&gt;
lemma par_imp_even_5: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
proof (induction rule: par.induct)&lt;br /&gt;
  show &amp;quot;even 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n::nat&lt;br /&gt;
  assume H1: &amp;quot;n ∈ par&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even n&amp;quot;&lt;br /&gt;
  then show &amp;quot;even (Suc (Suc n))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Lema: Un número n es par syss es divisible por 2.›&lt;br /&gt;
&lt;br /&gt;
theorem par_iff_even: &amp;quot;(n ∈ par) = (even n)&amp;quot; &lt;br /&gt;
  using even_imp_par par_imp_even_5 by blast&lt;br /&gt;
&lt;br /&gt;
subsection ‹Generalización y regla de inducción›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  · Antes de aplicar inducción se debe de generalizar la fórmula a&lt;br /&gt;
    probar.&lt;br /&gt;
 &lt;br /&gt;
  · Vamos a ilustrar el principio anterior en el caso de los conjuntos&lt;br /&gt;
    inductivamente definidos, con el siguiente ejemplo: si n+2 es par,&lt;br /&gt;
    entonces n también lo es.&lt;br /&gt;
&lt;br /&gt;
  · El siguiente intento falla:&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;Suc (Suc n) ∈ par ⟹ n ∈ par&amp;quot;&lt;br /&gt;
  apply (erule par.induct) &lt;br /&gt;
    (* 1. n ∈ par&lt;br /&gt;
       2. ⋀na. ⟦na ∈ par; n ∈ par⟧ ⟹ n ∈ par *)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  En el intento anterior, los subobjetivos generados son&lt;br /&gt;
     1. n ∈ par&lt;br /&gt;
     2. ⋀na. ⟦na ∈ par; n ∈ par⟧ ⟹ n ∈ par&lt;br /&gt;
  que no se pueden demostrar.&lt;br /&gt;
&lt;br /&gt;
  Se ha perdido la información sobre Suc (Suc n).&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹Reformulación del lema: Si n es par, entonces n-2 también lo es.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma par_imp_par_menos: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ n - 2 ∈ par&amp;quot;&lt;br /&gt;
  apply (induction rule: par.induct) &lt;br /&gt;
     (* 1. 0 - 2 ∈ par&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par *)&lt;br /&gt;
   apply auto&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma par_imp_par_menos_2: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ n - 2 ∈ par&amp;quot;&lt;br /&gt;
  by (induction rule: par.induct) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;n ∈  par ⟹ n - 2 ∈ par&amp;quot;&lt;br /&gt;
proof (induction rule: par.induct)&lt;br /&gt;
  show &amp;quot;0 - 2 ∈ par&amp;quot; &lt;br /&gt;
    by auto&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par&amp;quot; &lt;br /&gt;
    by auto&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Con el lema anterior se puede demostrar el original.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;Suc (Suc n) ∈ par ⟹ n ∈ par&amp;quot;&lt;br /&gt;
  apply (drule par_imp_par_menos_2)&lt;br /&gt;
    (* Suc (Suc n) - 2 ∈ par ⟹ n ∈ par *)&lt;br /&gt;
  apply simp&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma Suc_Suc_par_imp_par: &lt;br /&gt;
  &amp;quot;Suc (Suc n) ∈ par ⟹ n ∈ par&amp;quot; &lt;br /&gt;
  by (drule par_imp_par_menos_2, simp)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;Suc (Suc n) ∈ par&amp;quot; &lt;br /&gt;
  shows   &amp;quot;n ∈ par&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;Suc (Suc n) - 2 ∈ par&amp;quot; &lt;br /&gt;
    using assms by (rule par_imp_par_menos_2)&lt;br /&gt;
  then show &amp;quot;n ∈ par&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Lemma. Un número natural n es par syss n+2 es par.›&lt;br /&gt;
&lt;br /&gt;
lemma [iff]: &amp;quot;((Suc (Suc n)) ∈ par) = (n ∈ par)&amp;quot;&lt;br /&gt;
  using Suc_Suc_par_imp_par by blast&lt;br /&gt;
&lt;br /&gt;
text ‹Se usa el atributo &amp;quot;iff&amp;quot; porque sirve como regla de &lt;br /&gt;
  simplificación.›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Definiciones mutuamente inductivas›&lt;br /&gt;
&lt;br /&gt;
text ‹Definición cruzada de los conjuntos inductivos de los pares y de los &lt;br /&gt;
  impares:›&lt;br /&gt;
&lt;br /&gt;
inductive_set&lt;br /&gt;
  Pares    :: &amp;quot;nat set&amp;quot; and&lt;br /&gt;
  Impares  :: &amp;quot;nat set&amp;quot;&lt;br /&gt;
where&lt;br /&gt;
  ceroP:    &amp;quot;0 ∈ Pares&amp;quot;&lt;br /&gt;
| ParesI:   &amp;quot;n ∈ Impares ⟹ Suc n ∈ Pares&amp;quot;&lt;br /&gt;
| ImparesI: &amp;quot;n ∈ Pares   ⟹ Suc n ∈ Impares&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹El esquema de inducción generado por la definición anterior es&lt;br /&gt;
  · Pares_Impares.induct:&lt;br /&gt;
    ⟦P1 0; &lt;br /&gt;
     ⋀n. ⟦n ∈ Impares; P2 n⟧ ⟹ P1 (Suc n);&lt;br /&gt;
     ⋀n. ⟦n ∈ Pares;   P1 n⟧ ⟹ P2 (Suc n)⟧&lt;br /&gt;
    ⟹ (x1 ∈ Pares ⟶ P1 x1) ∧ (x2 ∈ Impares ⟶ P2 x2)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm Pares_Impares.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración usando el esquema anterior.›&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))&amp;quot;&lt;br /&gt;
  apply (induction rule: Pares_Impares.induct)&lt;br /&gt;
      (* 1. even 0&lt;br /&gt;
         2. ⋀n. ⟦n ∈ Impares; even (Suc n)⟧ ⟹ even (Suc n)&lt;br /&gt;
         3. ⋀n. ⟦n ∈ Pares; even n⟧ ⟹ even (Suc (Suc n))*)&lt;br /&gt;
    apply auto&lt;br /&gt;
      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))&amp;quot;&lt;br /&gt;
  by (induction rule: Pares_Impares.induct) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &amp;quot;(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))&amp;quot;&lt;br /&gt;
proof (induction rule: Pares_Impares.induct)&lt;br /&gt;
  show &amp;quot;even (0::nat)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  assume H1: &amp;quot;n ∈ Impares&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even (Suc n)&amp;quot;&lt;br /&gt;
  show &amp;quot;even (Suc n)&amp;quot; &lt;br /&gt;
    using H2 by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  assume H1: &amp;quot;n ∈ Pares&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even n&amp;quot;&lt;br /&gt;
  have &amp;quot;∃k. n = 2*k&amp;quot; &lt;br /&gt;
    using H2 by (simp add: dvd_def)&lt;br /&gt;
  then obtain k where &amp;quot;n = 2*k&amp;quot; &lt;br /&gt;
    by (rule exE)&lt;br /&gt;
  then have &amp;quot;Suc (Suc n) = 2*(k+1)&amp;quot; &lt;br /&gt;
    by auto&lt;br /&gt;
  then have &amp;quot;∃k. Suc (Suc n) = 2*k&amp;quot; &lt;br /&gt;
    by (rule exI)&lt;br /&gt;
  then show &amp;quot;even (Suc (Suc n))&amp;quot; &lt;br /&gt;
    by (simp add: dvd_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection ‹Definición inductiva de predicados›&lt;br /&gt;
&lt;br /&gt;
text ‹Definición inductiva del predicado es_par tal que (es_par n) se&lt;br /&gt;
  verifica si n es par.›&lt;br /&gt;
&lt;br /&gt;
inductive es_par :: &amp;quot;nat ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;es_par 0&amp;quot; &lt;br /&gt;
| &amp;quot;es_par n ⟹ es_par (Suc (Suc n))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Heurística para elegir entre definir conjuntos o predicados:&lt;br /&gt;
  · si se va a combinar con operaciones conjuntistas, definir conjunto;&lt;br /&gt;
  · en caso contrario, definir predicado.›&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=827</id>
		<title>Desarrollo de teorías formalizadas con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=827"/>
		<updated>2020-05-20T15:20:32Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Desarrollo de teorías formalizadas›&lt;br /&gt;
&lt;br /&gt;
theory T11_Desarrollo_de_teorias_formalizadas&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section ‹Desarrollo de la teoría de grupos›&lt;br /&gt;
&lt;br /&gt;
text ‹El objetivo de este tema es mostrar cómo se puede trabajar en&lt;br /&gt;
  estructuras algebraicas por medio de locales. &lt;br /&gt;
&lt;br /&gt;
  Se usará como ejemplo la teoría de grupos.›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 1. Un grupo es una estructura (G,·,𝟭,^) tal que &lt;br /&gt;
  * G es un conjunto, &lt;br /&gt;
  * · es una operación binaria en G, &lt;br /&gt;
  * 𝟭 es un elemento de G y &lt;br /&gt;
  * ^ es una función de G en G &lt;br /&gt;
  tales que se cumplen las siguientes propiedades:&lt;br /&gt;
  * asociativa: ∀x y z. x ⋅ (y ⋅ z) = (x ⋅ y) ⋅ z&lt;br /&gt;
  * neutro por la izquierda: ∀x. 𝟭 ⋅ x = x&lt;br /&gt;
  * inverso por la izquierda: ∀x. x^ ⋅ x = 𝟭 &lt;br /&gt;
&lt;br /&gt;
  Definir el entorno axiomático de los grupos.›&lt;br /&gt;
&lt;br /&gt;
locale grupo = &lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Notas sobre notación:&lt;br /&gt;
  * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
  * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
  * El inverso de x es x^ y se escribe pulsando 2 veces en ^.›&lt;br /&gt;
&lt;br /&gt;
text ‹A continuación se crea un contexto en el que se supone la &lt;br /&gt;
  notación y axiomas de grupos. &lt;br /&gt;
&lt;br /&gt;
  En el contexto se demuestran propiedades de los grupos.›&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 2. En los grupos, x^ también es el inverso de x por la&lt;br /&gt;
  derecha; es decir &lt;br /&gt;
     x ⋅ x^ = 𝟭›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
  (* sledgehammer *)&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inverso_d: &lt;br /&gt;
  &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ x^ = 𝟭 ⋅ (x ⋅ x^)&amp;quot; &lt;br /&gt;
    by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = (𝟭 ⋅ x) ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (((x^)^ ⋅ x^) ⋅ x) ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ (x^ ⋅ x)) ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ 𝟭) ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ (𝟭 ⋅ x^)&amp;quot; &lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = 𝟭&amp;quot; &lt;br /&gt;
    by (simp only: inverso_i)&lt;br /&gt;
  finally show ?thesis &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 2. En los grupos, 𝟭 también es el neutro por la derecha; &lt;br /&gt;
  es decir &lt;br /&gt;
     x ⋅ 𝟭 = x›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma neutro_d: &lt;br /&gt;
  &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ 𝟭 = x ⋅ (x^ ⋅ x)&amp;quot; &lt;br /&gt;
    by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x ⋅ x^) ⋅ x&amp;quot;&lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⋅ x&amp;quot; &lt;br /&gt;
    by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;… = x&amp;quot; &lt;br /&gt;
    by (simp only: neutro_i)&lt;br /&gt;
  finally show &amp;quot;x ⋅ 𝟭 = x&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed &lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 3. En los grupos, se tiene la propiedad cancelativa por la&lt;br /&gt;
  izquierda; es decir,&lt;br /&gt;
     x ⋅ y = x ⋅ z syss y = z›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma cancelativa_i: &lt;br /&gt;
  &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;x ⋅ y = x ⋅ z&amp;quot;&lt;br /&gt;
  then have &amp;quot;x^ ⋅ (x ⋅ y) = x^ ⋅ (x ⋅ z)&amp;quot;&lt;br /&gt;
    by (simp only: arg_cong [of &amp;quot;x ⋅ y&amp;quot; &amp;quot;x ⋅ z&amp;quot;])&lt;br /&gt;
  then have &amp;quot;(x^ ⋅ x) ⋅ y = (x^ ⋅ x) ⋅ z&amp;quot; &lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  then have &amp;quot;𝟭 ⋅ y = 𝟭 ⋅ z&amp;quot; &lt;br /&gt;
    by (simp only: inverso_i)&lt;br /&gt;
  thus &amp;quot;y = z&amp;quot; &lt;br /&gt;
    by (simp only: neutro_i)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;y = z&amp;quot;&lt;br /&gt;
  then show &amp;quot;x ⋅ y = x ⋅ z&amp;quot; &lt;br /&gt;
    by (simp only: arg_cong [of &amp;quot;y&amp;quot; &amp;quot;z&amp;quot;])&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 4. En los grupos, el elemento neutro por la izquierda es&lt;br /&gt;
  único; es decir, si e es un elemento tal que para todo x se tiene que &lt;br /&gt;
  e ⋅ x = x, entonces e = 𝟭.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_neutro_i:&lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;𝟭 = x ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = (e ⋅ x) ⋅ x^&amp;quot; &lt;br /&gt;
    using assms [THEN sym] &lt;br /&gt;
    by (rule arg_cong [of &amp;quot;x&amp;quot; &amp;quot;e ⋅ x&amp;quot; &amp;quot;λy. y ⋅ x^&amp;quot;])&lt;br /&gt;
  also have &amp;quot;... = e ⋅ (x ⋅ x^)&amp;quot; &lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = e ⋅ 𝟭&amp;quot; &lt;br /&gt;
    by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = e&amp;quot; &lt;br /&gt;
    by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis &lt;br /&gt;
    by this&lt;br /&gt;
qed &lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 5. En los grupos, los inversos por la izquierda son &lt;br /&gt;
  únicos; es decir, si x&amp;#039; es un elemento tal que x&amp;#039; ⋅ x = 𝟭, entonces &lt;br /&gt;
  x^ = x&amp;#039;.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_inverso_i:&lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x^ = 𝟭 ⋅ x^&amp;quot; &lt;br /&gt;
    by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;... = (x&amp;#039; ⋅ x) ⋅ x^&amp;quot; &lt;br /&gt;
    using assms [THEN sym] &lt;br /&gt;
    by (simp only: arg_cong [of &amp;quot;𝟭&amp;quot; &amp;quot;x&amp;#039; ⋅ x&amp;quot;])&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ (x ⋅ x^)&amp;quot; &lt;br /&gt;
    by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ 𝟭&amp;quot; &lt;br /&gt;
    by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039;&amp;quot; &lt;br /&gt;
    by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 6. En los grupos, es inverso de un producto es el &lt;br /&gt;
  producto de los inversos cambiados de orden; es decir,&lt;br /&gt;
     (x ⋅ y)^ = y^ ⋅ x^›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inversa_producto:&lt;br /&gt;
  &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = 𝟭&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = (y^ ⋅ (x^ ⋅ x)) ⋅ y&amp;quot; &lt;br /&gt;
      by (simp only: asociativa)&lt;br /&gt;
    also have &amp;quot;... = (y^ ⋅ 𝟭) ⋅ y&amp;quot; &lt;br /&gt;
      by (simp only: inverso_i)&lt;br /&gt;
    also have &amp;quot;... = y^ ⋅ y&amp;quot; &lt;br /&gt;
      by (simp only: neutro_d)&lt;br /&gt;
    also have &amp;quot;... = 𝟭&amp;quot; &lt;br /&gt;
      by (simp only: inverso_i)&lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 7. En los grupos, el inverso del inverso es el propio&lt;br /&gt;
  elemento; es decir, &lt;br /&gt;
     (x^)^ = x›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
  using inverso_d unicidad_inverso_i by blast&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma inverso_inverso: &lt;br /&gt;
  &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;x ⋅ x^ = 𝟭&amp;quot; &lt;br /&gt;
    by (simp only: inverso_d)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 8. En los grupos, la función inversa es inyectiva; es &lt;br /&gt;
  decir, si x e y tienen los mismos inversos, entonces son iguales.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis inverso_inverso)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática estructurada es›&lt;br /&gt;
lemma inversa_inyectiva:&lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(x^)^ = (y^)^&amp;quot; &lt;br /&gt;
    using assms by (simp only: arg_cong [of &amp;quot;x^&amp;quot; &amp;quot;y^&amp;quot;])&lt;br /&gt;
  thus &amp;quot;x = y&amp;quot; &lt;br /&gt;
    by (simp only: inverso_inverso)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section ‹Teorías de órdenes mediante clases›&lt;br /&gt;
&lt;br /&gt;
text ‹El tutorial sobre clases está en la teoría Clases.thy.&lt;br /&gt;
  &lt;br /&gt;
  La clase de los órdenes es la colección de los tipos que poseen una&lt;br /&gt;
  relación ≼ verificando las siguientes propiedades&lt;br /&gt;
  · reflexiva: x ≼ x&lt;br /&gt;
  · transitiva: ⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&lt;br /&gt;
  · antisimétrica: ⟦x ≼ y; y ≼ x⟧ ⟹ x = y&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
class orden = &lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≼&amp;quot; 50)&lt;br /&gt;
  assumes refl: &amp;quot;x ≼ x&amp;quot;&lt;br /&gt;
      and trans: &amp;quot;⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ≼ y; y ≼ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ha generado los teoremas correspondientes a los axiomas. Pueden &lt;br /&gt;
  consultarse mediante thm como se muestra a continuación.›&lt;br /&gt;
&lt;br /&gt;
thm trans&lt;br /&gt;
&lt;br /&gt;
text ‹Se inicia el contexto orden en el que se van a realizar &lt;br /&gt;
  definiciones y demostraciones.›&lt;br /&gt;
&lt;br /&gt;
context orden&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹x es menor que y si x es menor o igual que y y no es menos o igual &lt;br /&gt;
  que x.›&lt;br /&gt;
&lt;br /&gt;
definition menor :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≺&amp;quot; 50)&lt;br /&gt;
  where &amp;quot;x ≺ y ⟷ x ≼ y ∧ ¬ y ≼ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹La relación menor es irreflexiva.›&lt;br /&gt;
&lt;br /&gt;
lemma irrefl: &amp;quot;¬ x ≺ x&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
text ‹La relación menor es transitiva.›&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
    (* ⟦x ≼ y ∧ ¬ y ≼ x; y ≼ z ∧ ¬ z ≼ y⟧ ⟹ x ≼ z ∧ ¬ z ≼ x *)&lt;br /&gt;
  apply (auto intro: trans)&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma menor_trans: &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def intro: trans)&lt;br /&gt;
&lt;br /&gt;
text ‹La relación menor es asimétrica; es decir, si x ≺ y e y ≺ x, &lt;br /&gt;
  entonces se verifica cualquier propiedad P. ›&lt;br /&gt;
&lt;br /&gt;
lemma asimetrica: &amp;quot;x ≺ y ⟹ y ≺ x ⟹ P&amp;quot;&lt;br /&gt;
  by (simp add: menor_def)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection ‹Subclase›&lt;br /&gt;
&lt;br /&gt;
text ‹Un orden lineal es un orden en que cada par de elementos son &lt;br /&gt;
  comparables.›&lt;br /&gt;
&lt;br /&gt;
class ordenLineal = orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ≼ y ∨ y ≼ x&amp;quot;&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En los órdenes lineales se tiene que x ≺ y ∨ x = y ∨ y ≺ x.›&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
      (* (x ≼ y ∧ ¬ y ≼ x) ∨ x = y ∨ (y ≼ x ∧ ¬ x ≼ y) *)&lt;br /&gt;
  apply auto&lt;br /&gt;
      (*  1. ⟦x ≠ y; ¬ x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
          2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (cut_tac x=x and y=y in lineal)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y ∨ y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (erule disjE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply (erule_tac P=&amp;quot;x ≼ y&amp;quot; in notE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
  apply (drule antisim)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* 1. ⟦x ≼ y; y = x⟧ ⟹ x = y *)&lt;br /&gt;
  apply (erule sym)&lt;br /&gt;
      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  using antisim lineal menor_def by auto&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section ‹Teoría de órdenes mediante ámbitos (&amp;quot;Locales&amp;quot;)›&lt;br /&gt;
&lt;br /&gt;
text ‹Un orden es una estructura con una relación reflexiva, &lt;br /&gt;
  transitiva y antisimétrica.›&lt;br /&gt;
&lt;br /&gt;
locale Orden =&lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;⊑&amp;quot; 50)&lt;br /&gt;
  assumes refl:    &amp;quot;x ⊑ x&amp;quot;&lt;br /&gt;
      and trans:   &amp;quot;⟦x ⊑ y; y ⊑ z⟧ ⟹ x ⊑ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ⊑ y; y ⊑ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Los teoremas se diferencian por el nombre y el ámbito. &lt;br /&gt;
  Por ejemplo,&lt;br /&gt;
    refl: ?x ≼ ?x&lt;br /&gt;
    Orden.refl: Orden ?menor_ig ⟹ ?menor_ig ?x ?x&lt;br /&gt;
    Orden_def: Orden ?menor_ig ≡&lt;br /&gt;
               (∀x. ?menor_ig x x) ∧&lt;br /&gt;
               (∀x y z. ?menor_ig x y ⟶ ?menor_ig y z ⟶ ?menor_ig x z) ∧&lt;br /&gt;
               (∀x y. ?menor_ig x y ⟶ ?menor_ig y x ⟶ x = y)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm refl&lt;br /&gt;
thm Orden.refl&lt;br /&gt;
thm Orden_def&lt;br /&gt;
&lt;br /&gt;
text ‹Un orden lineal es un orden en el que todos los pares de elementos son &lt;br /&gt;
  comparables.›&lt;br /&gt;
&lt;br /&gt;
locale OrdenLineal = Orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ⊑ y ∨ y ⊑ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Los boooleanos está ordenados con el condicional.›&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_imp: Orden &amp;quot;λx y. x ⟶ y&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix P show &amp;quot;P ⟶ P&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix P Q R show &amp;quot;P ⟶ Q ⟹ Q ⟶ R ⟹ P ⟶ R&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix P Q show &amp;quot;P ⟶ Q ⟹ Q ⟶ P ⟹ P = Q&amp;quot; by blast&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Los naturales con la relación de divisibilidad es un conjunto &lt;br /&gt;
  ordenado.›&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_dvd: Orden &amp;quot;(dvd) :: nat ⇒ nat ⇒ bool&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x :: nat&lt;br /&gt;
  show &amp;quot;x dvd x&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x y z :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd z⟧ ⟹ x dvd z&amp;quot; by auto &lt;br /&gt;
next&lt;br /&gt;
  fix x y :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd x⟧ ⟹ x = y&amp;quot; by auto&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Semigrupos, monoides y grupos›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Definición de clases›&lt;br /&gt;
&lt;br /&gt;
text ‹Un semigrupo es una estructura compuesta por un conjunto A y una&lt;br /&gt;
  operación binaria en A.›&lt;br /&gt;
&lt;br /&gt;
class semigrupo =&lt;br /&gt;
  fixes mult :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⊗&amp;quot; 70) &lt;br /&gt;
  assumes asoc: &amp;quot;(x ⊗ y) ⊗ z = x ⊗ (y ⊗ z )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection ‹Instanciación de clases›&lt;br /&gt;
&lt;br /&gt;
text ‹Los enteros con la suma forman un semigrupo.›&lt;br /&gt;
&lt;br /&gt;
instantiation int :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
definition &lt;br /&gt;
  mult_int_def: &amp;quot;i ⊗ j = i + (j ::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i j k :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;(i + j ) + k = i + (j + k)&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;(i ⊗ j ) ⊗ k = i ⊗ (j ⊗ k)&amp;quot; unfolding mult_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
text ‹Los naturales con la suma forman un semigrupo.›&lt;br /&gt;
&lt;br /&gt;
instantiation nat :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
fun mult_nat where &lt;br /&gt;
  &amp;quot;(0::nat) ⊗ n = n&amp;quot; &lt;br /&gt;
| &amp;quot;Suc m ⊗ n = Suc (m ⊗ n)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix m n q :: &amp;quot;nat&amp;quot; &lt;br /&gt;
  show &amp;quot;m ⊗ n ⊗ q = m ⊗ (n ⊗ q)&amp;quot; &lt;br /&gt;
    by (induct m) auto&lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection ‹Instancias recursivas›&lt;br /&gt;
&lt;br /&gt;
text ‹Si (A,⊗) y (B,⊗) son semigrupos, entonces ((A×B,⊗), donde el &lt;br /&gt;
  producto se define por &lt;br /&gt;
     (x,y)⊗(x&amp;#039;,y&amp;#039;) = (x⊗x&amp;#039;,y⊗y&amp;#039;),&lt;br /&gt;
  es un semigrupo.›&lt;br /&gt;
 &lt;br /&gt;
instantiation prod :: (semigrupo, semigrupo) semigrupo &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  mult_prod_def : &amp;quot;p1 ⊗ p2 = (fst p1 ⊗ fst p2, snd p1 ⊗ snd p2)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p1 p2 p3 :: &amp;quot;&amp;#039;a::semigrupo × &amp;#039;b::semigrupo&amp;quot; &lt;br /&gt;
  show &amp;quot;(p1 ⊗ p2) ⊗ p3 = p1 ⊗ (p2 ⊗ p3)&amp;quot; &lt;br /&gt;
    unfolding mult_prod_def by (simp add: asoc) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection ‹Subclases›&lt;br /&gt;
&lt;br /&gt;
text ‹ Un monoide izquierdo es un semigrupo con elemento neutro por la &lt;br /&gt;
  izquierda.›&lt;br /&gt;
&lt;br /&gt;
class monoideI = semigrupo + &lt;br /&gt;
  fixes neutro :: &amp;quot;&amp;#039;a&amp;quot; (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
  assumes neutroI: &amp;quot;𝟭 ⊗ x = x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Los naturales y los enteros con la suma forman monoides por la &lt;br /&gt;
  izquierda.›&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_nat_def : &amp;quot;𝟭 = (0::nat)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_int_def : &amp;quot;𝟭 = (0::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ n = n&amp;quot; unfolding neutro_nat_def by simp&lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ k = k&amp;quot; unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text ‹El producto de dos monoides por la izquierda es un monoide por la&lt;br /&gt;
  izquierda, donde el neutro es el par formado por los elementos &lt;br /&gt;
  neutros.›&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoideI , monoideI) monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_prod_def : &amp;quot;𝟭 = (𝟭, 𝟭)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoideI × &amp;#039;b::monoideI&amp;quot; &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ p = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutroI) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text ‹Un monoide es un monoide por la izquierda cuyo elemento neutro &lt;br /&gt;
  por la izquierda lo es también por la derecha.›&lt;br /&gt;
&lt;br /&gt;
class monoide = monoideI + &lt;br /&gt;
  assumes neutro: &amp;quot;x ⊗ 𝟭 = x&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text ‹Los naturales y los enteros con la suma son monoides.›&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;n ⊗ 𝟭 = n&amp;quot; &lt;br /&gt;
    unfolding neutro_nat_def by (induct n) simp_all &lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;k ⊗ 𝟭 = k&amp;quot; &lt;br /&gt;
    unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text ‹El producto de dos monoides es un monoide.›&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoide, monoide) monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoide × &amp;#039;b::monoide&amp;quot; &lt;br /&gt;
  show &amp;quot;p ⊗ 𝟭 = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutro) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text ‹Un grupo es un monoide por la izquierda tal que todo elemento &lt;br /&gt;
  posee un inverso por la izquierda.›&lt;br /&gt;
&lt;br /&gt;
class grupo2 = monoideI + &lt;br /&gt;
  fixes inverso :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a&amp;quot; (&amp;quot;(_⇧-⇧1)&amp;quot; [1000] 999)&lt;br /&gt;
  assumes inversoI: &amp;quot;x⇧-⇧1 ⊗ x = 𝟭&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text ‹Los enteros con la suma forman un grupo.›&lt;br /&gt;
&lt;br /&gt;
instantiation int :: grupo2 &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition&lt;br /&gt;
  inverso_int_def: &amp;quot;i⇧-⇧1 = -(i::int)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;-i + i = 0&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;i⇧-⇧1 ⊗ i = 𝟭&amp;quot; &lt;br /&gt;
    unfolding mult_int_def neutro_int_def inverso_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection ‹Razonamiento abstracto›&lt;br /&gt;
&lt;br /&gt;
text ‹En los grupos se verifica la propiedad cancelativa por la &lt;br /&gt;
  izquierda, i.e.&lt;br /&gt;
     x ⊗ y = x ⊗ z ⟷ y = z&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
lemma (in grupo2) cancelativa_izq: &amp;quot;x ⊗ y = x ⊗ z ⟷ y = z&amp;quot; &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;x ⊗ y = x ⊗ z&amp;quot;&lt;br /&gt;
  then have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ y) = x⇧-⇧1 ⊗ (x ⊗ z)&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
  then have &amp;quot;(x⇧-⇧1 ⊗ x) ⊗ y = (x⇧-⇧1 ⊗ x) ⊗ z&amp;quot; &lt;br /&gt;
    using asoc by simp &lt;br /&gt;
  then show &amp;quot;y = z&amp;quot; &lt;br /&gt;
    using neutroI and inversoI by simp&lt;br /&gt;
next &lt;br /&gt;
  assume &amp;quot;y = z&amp;quot; &lt;br /&gt;
  then show &amp;quot;x ⊗ y = x ⊗ z&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
thm grupo2.cancelativa_izq&lt;br /&gt;
&lt;br /&gt;
text ‹Se genera el teorema grupo.cancelativa_izq&lt;br /&gt;
     class.grupo2 ?mult ?neutro ?inverso ⟹ &lt;br /&gt;
     (?mult ?x ?y = ?mult ?x ?z) = (?y = ?z)&lt;br /&gt;
&lt;br /&gt;
  El teorema se aplica automáticamente a todas las instancias de la &lt;br /&gt;
  clase grupo. Por ejemplo, a los enteros.›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Definiciones derivadas›&lt;br /&gt;
&lt;br /&gt;
text ‹En los monoides se define la potencia natural por&lt;br /&gt;
  · x^0     = 1&lt;br /&gt;
  · x^{n+1} = x*x^n&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
fun (in monoide) potencia_nat :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_nat 0 x       = 𝟭&amp;quot;  &lt;br /&gt;
| &amp;quot;potencia_nat (Suc n) x = x ⊗ potencia_nat n x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection ‹Analogía entre clases y functores›&lt;br /&gt;
&lt;br /&gt;
text ‹Las listas con la operación de concatenación y la lista vacía &lt;br /&gt;
  como elemento neutro forman un monoide.›&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;⋀x y z. (x @ y) @ z = x @ (y @ z)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. [] @ x = x&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. x @ [] = x&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden aplicar propiedades de los monides a las listas. Por &lt;br /&gt;
  ejemplo,›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;append [] xs = xs&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text ‹(repite n xs) es la lista obtenida concatenando n veces la lista &lt;br /&gt;
  xs.›&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where &lt;br /&gt;
  &amp;quot;repite 0 _        = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) xs = xs @ repite n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide. Además, la potencia natural se intepreta &lt;br /&gt;
  como repite.›&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; rewrites&lt;br /&gt;
  &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
proof -&lt;br /&gt;
  interpret monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; .. &lt;br /&gt;
  show &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
  proof &lt;br /&gt;
    fix n &lt;br /&gt;
    show &amp;quot;monoide.potencia_nat append [] n = repite n&amp;quot;&lt;br /&gt;
      by (induct n) auto &lt;br /&gt;
  qed &lt;br /&gt;
qed intro_locales&lt;br /&gt;
&lt;br /&gt;
subsection ‹Relaciones de subclase adicionales›&lt;br /&gt;
&lt;br /&gt;
text ‹Los grupos son monoides.›&lt;br /&gt;
&lt;br /&gt;
subclass (in grupo2) monoide &lt;br /&gt;
proof &lt;br /&gt;
  fix x &lt;br /&gt;
  have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ (x ⊗ (x⇧-⇧1 ⊗ x))&amp;quot; &lt;br /&gt;
    using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = (x⇧-⇧1 ⊗ x) ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; &lt;br /&gt;
    using asoc [symmetric] by simp&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; &lt;br /&gt;
    using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = x⇧-⇧1 ⊗ x&amp;quot; &lt;br /&gt;
    using neutroI by simp&lt;br /&gt;
  finally have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ x&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
  then show &amp;quot;x ⊗ 𝟭 = x&amp;quot; &lt;br /&gt;
    using cancelativa_izq by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹La potencia entera en los grupos se define a partir de la potencia &lt;br /&gt;
  natural como sigue:&lt;br /&gt;
  · x^k = x^k si k ≥ 0&lt;br /&gt;
  · x^k = (x^{-k})^{-1}, en caso contrario.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
definition (in grupo2) potencia_entera :: &amp;quot;int ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_entera k x = &lt;br /&gt;
   (if k &amp;gt;= 0 &lt;br /&gt;
    then potencia_nat (nat k) x &lt;br /&gt;
    else (potencia_nat (nat (- k)) x)⇧-⇧1)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
section ‹Bibliografía›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  + &amp;quot;Haskell-style type classes with Isabelle/Isar&amp;quot; ~ F. Haftmann.&lt;br /&gt;
    http://bit.ly/2E55pAJ&lt;br /&gt;
  + &amp;quot;Tutorial to locales and locale interpretation&amp;quot; ~ C. Ballarin.&lt;br /&gt;
    http://bit.ly/2E3ozXB  &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=826</id>
		<title>Desarrollo de teorías formalizadas con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=826"/>
		<updated>2020-05-20T15:19:48Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Desarrollo de teorías formalizadas *}&lt;br /&gt;
&lt;br /&gt;
theory T11_Desarrollo_de_teorias_formalizadas&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section {* Desarrollo de la teoría de grupos*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El objetivo de este tema es mostrar cómo se puede trabajar en&lt;br /&gt;
  estructuras algebraicas por medio de locales. Se usará como ejemplo la&lt;br /&gt;
  teoría de grupos. *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 1. Un grupo es una estructura (G,·,𝟭,^) tal que G es un&lt;br /&gt;
  conjunto, · es una operación binaria en G, 𝟭 es un elemento de G y ^&lt;br /&gt;
  es una función de G en G tales que se cumplen las siguientes&lt;br /&gt;
  propiedades:&lt;br /&gt;
  * asociativa: ∀x y z. x ⋅ (y ⋅ z) = (x ⋅ y) ⋅ z&lt;br /&gt;
  * neutro por la izquierda: ∀x. 𝟭 ⋅ x = x&lt;br /&gt;
  * inverso por la izquierda: ∀x. x^ ⋅ x = 𝟭 &lt;br /&gt;
  Definir el entorno axiomático de los grupos. *}&lt;br /&gt;
&lt;br /&gt;
locale grupo = &lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Notas sobre notación:&lt;br /&gt;
  * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
  * El neutro es 𝟭 y se escribe con \ y &amp;lt;one&amp;gt; (sin espacio entre ellos).&lt;br /&gt;
  * El inverso de x es x^ y se escribe con pulsando 2 veces en ^. *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  A continuación se crea un contexto en el que se supone la notación y&lt;br /&gt;
  axiomas de grupos. En el contexto se demuestran propiedades de los&lt;br /&gt;
  grupos. *}&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. En los grupos, x^ también es el inverso de x por la&lt;br /&gt;
  derecha; es decir &lt;br /&gt;
     x ⋅ x^ = 𝟭   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inverso_d: &lt;br /&gt;
  &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ x^ = 𝟭 ⋅ (x ⋅ x^)&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = (𝟭 ⋅ x) ⋅ x^&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (((x^)^ ⋅ x^) ⋅ x) ⋅ x^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ (x^ ⋅ x)) ⋅ x^&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ 𝟭) ⋅ x^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ (𝟭 ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ x^&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. En los grupos, 𝟭 también es el neutro por la derecha; es decir &lt;br /&gt;
     x ⋅ 𝟭 = x   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma neutro_d: &lt;br /&gt;
  &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ 𝟭 = x ⋅ (x^ ⋅ x)&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x ⋅ x^) ⋅ x&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⋅ x&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;… = x&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  finally show &amp;quot;x ⋅ 𝟭 = x&amp;quot; .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 3. En los grupos, se tiene la propiedad cancelativa por la&lt;br /&gt;
  izquierda; es decir,&lt;br /&gt;
     x ⋅ y = x ⋅ z syss y = z   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma cancelativa_i: &lt;br /&gt;
  &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;x ⋅ y = x ⋅ z&amp;quot;&lt;br /&gt;
  hence &amp;quot;x^ ⋅ (x ⋅ y) = x^ ⋅ (x ⋅ z)&amp;quot; by simp&lt;br /&gt;
  hence &amp;quot;(x^ ⋅ x) ⋅ y = (x^ ⋅ x) ⋅ z&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  hence &amp;quot;𝟭 ⋅ y = 𝟭 ⋅ z&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  thus &amp;quot;y = z&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;y = z&amp;quot;&lt;br /&gt;
  then show &amp;quot;x ⋅ y = x ⋅ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 4. En los grupos, el elemento neutro por la izquierda es&lt;br /&gt;
  único; es decir, si e es un elemento tal que para todo x se tiene que &lt;br /&gt;
  e ⋅ x = x, entonces e = 𝟭. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_neutro_i:&lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;𝟭 = x ⋅ x^&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = (e ⋅ x) ⋅ x^&amp;quot; using assms by simp&lt;br /&gt;
  also have &amp;quot;... = e ⋅ (x ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = e ⋅ 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = e&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 5. En los grupos, los inversos por la izquierda son únicos; es&lt;br /&gt;
  decir, si x&amp;#039; es un elemento tal que x&amp;#039; ⋅ x = 𝟭, entonces x^ x&amp;#039;. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_inverso_i:&lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x^ = 𝟭 ⋅ x^&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;... = (x&amp;#039; ⋅ x) ⋅ x^&amp;quot; using assms by simp&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ (x ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039;&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 6. En los grupos, es inverso de un producto es el producto de&lt;br /&gt;
  los inversos cambiados de orden; es decir,&lt;br /&gt;
     (x ⋅ y)^ = y^ ⋅ x^    *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inversa_producto:&lt;br /&gt;
  &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = 𝟭&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = (y^ ⋅ (x^ ⋅ x)) ⋅ y&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    also have &amp;quot;... = (y^ ⋅ 𝟭) ⋅ y&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    also have &amp;quot;... = y^ ⋅ y&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
    also have &amp;quot;... = 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 7. En los grupos, el inverso del inverso es el propio&lt;br /&gt;
  elemento; es decir, &lt;br /&gt;
     (x^)^ = x    *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
  using inverso_d unicidad_inverso_i by blast&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma inverso_inverso: &lt;br /&gt;
  &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;x ⋅ x^ = 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 8. En los grupos, la función inversa es inyectiva; es decir,&lt;br /&gt;
  si x e y tienen los mismos inversos, entonces son iguales. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis inverso_inverso)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática estructurada es›&lt;br /&gt;
lemma inversa_inyectiva:&lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(x^)^ = (y^)^&amp;quot; using assms by simp&lt;br /&gt;
  thus &amp;quot;x = y&amp;quot; by (simp only: inverso_inverso)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Teorías de órdenes mediante clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El tutorial sobre clases está en la teoría Clases.thy.&lt;br /&gt;
  &lt;br /&gt;
  La clase de los órdenes es la colección de los tipos que poseen una&lt;br /&gt;
  relación ≼ verificando las siguientes propiedades&lt;br /&gt;
  · reflexiva: x ≼ x&lt;br /&gt;
  · transitiva: ⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&lt;br /&gt;
  · antisimétrica: ⟦x ≼ y; y ≼ x⟧ ⟹ x = y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class orden = &lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≼&amp;quot; 50)&lt;br /&gt;
  assumes refl: &amp;quot;x ≼ x&amp;quot;&lt;br /&gt;
      and trans: &amp;quot;⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ≼ y; y ≼ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ha generado los teoremas correspondientes a los axiomas. Pueden consultarse&lt;br /&gt;
  mediante thm como se muestra a continuación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm trans&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se inicia el contexto orden en el que se van a realizar definiciones y&lt;br /&gt;
  demostraciones. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
context orden&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  x es menor que y si x es menor o igual que y y no son iguales.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition menor :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≺&amp;quot; 50)&lt;br /&gt;
  where &amp;quot;x ≺ y ⟷ x ≼ y ∧ ¬ y ≼ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    La relación menor es irreflexiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma irrefl: &amp;quot;¬ x ≺ x&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La relación menor es transitiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
    (* ⟦x ≼ y ∧ ¬ y ≼ x; y ≼ z ∧ ¬ z ≼ y⟧ ⟹ x ≼ z ∧ ¬ z ≼ x *)&lt;br /&gt;
  apply (auto intro: trans)&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma menor_trans: &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def intro: trans)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La relación menor es asimétrica; es decir, si x ≺ y e y ≺ x, entonces&lt;br /&gt;
  se verifica cualquier propiedad P. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma asimetrica: &amp;quot;x ≺ y ⟹ y ≺ x ⟹ P&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Subclase *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden lineal es un orden en que cada par de elementos son comparables.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class ordenLineal = orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ≼ y ∨ y ≼ x&amp;quot;&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los órdenes lineales se tiene que x ≺ y ∨ x = y ∨ y ≺ x.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
      (* (x ≼ y ∧ ¬ y ≼ x) ∨ x = y ∨ (y ≼ x ∧ ¬ x ≼ y) *)&lt;br /&gt;
  apply auto&lt;br /&gt;
      (*  1. ⟦x ≠ y; ¬ x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
          2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (cut_tac x=x and y=y in lineal)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y ∨ y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (erule disjE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply (erule_tac P=&amp;quot;x ≼ y&amp;quot; in notE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
  apply (drule antisim)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* 1. ⟦x ≼ y; y = x⟧ ⟹ x = y *)&lt;br /&gt;
  apply (erule sym)&lt;br /&gt;
      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  using menor_def lineal antisim  &lt;br /&gt;
  by blast&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Teoría de órdenes mediante ámbitos (&amp;quot;Locales&amp;quot;) *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden es una estructura con una relación reflexiva, transitiva y&lt;br /&gt;
  antisimétrica. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale Orden =&lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;⊑&amp;quot; 50)&lt;br /&gt;
  assumes refl:    &amp;quot;x ⊑ x&amp;quot;&lt;br /&gt;
      and trans:   &amp;quot;⟦x ⊑ y; y ⊑ z⟧ ⟹ x ⊑ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ⊑ y; y ⊑ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    Los teoremas se diferencian por el nombre y el ámbito. Por ejemplo,&lt;br /&gt;
    refl: ?x ≼ ?x&lt;br /&gt;
    Orden.refl: Orden ?menor_ig ⟹ ?menor_ig ?x ?x&lt;br /&gt;
    Orden_def: Orden ?menor_ig ≡&lt;br /&gt;
               (∀x. ?menor_ig x x) ∧&lt;br /&gt;
               (∀x y z. ?menor_ig x y ⟶ ?menor_ig y z ⟶ ?menor_ig x z) ∧&lt;br /&gt;
               (∀x y. ?menor_ig x y ⟶ ?menor_ig y x ⟶ x = y)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm refl&lt;br /&gt;
thm Orden.refl&lt;br /&gt;
thm Orden_def&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden lineal es un orden en el que todos los pares de elementos son &lt;br /&gt;
  comparables. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale OrdenLineal = Orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ⊑ y ∨ y ⊑ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los boooleanos está ordenados con el condicional.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_imp: Orden &amp;quot;λx y. x ⟶ y&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix P show &amp;quot;P ⟶ P&amp;quot; by blast&lt;br /&gt;
next&lt;br /&gt;
  fix P Q R show &amp;quot;P ⟶ Q ⟹ Q ⟶ R ⟹ P ⟶ R&amp;quot; by blast&lt;br /&gt;
next&lt;br /&gt;
  fix P Q show &amp;quot;P ⟶ Q ⟹ Q ⟶ P ⟹ P = Q&amp;quot; by blast&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales con la relación de divisibilidad es un conjunto ordenado.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_dvd: Orden &amp;quot;(dvd) :: nat ⇒ nat ⇒ bool&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x :: nat&lt;br /&gt;
  show &amp;quot;x dvd x&amp;quot; using dvd_refl by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x y z :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd z⟧ ⟹ x dvd z&amp;quot; using dvd_trans by auto&lt;br /&gt;
next&lt;br /&gt;
  fix x y :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd x⟧ ⟹ x = y&amp;quot; using dvd_antisym by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ámbito de las funciones monótonas (ver la página 12 del tutorial de&lt;br /&gt;
  locales). &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale Mono =&lt;br /&gt;
  le1: Orden le1 +&lt;br /&gt;
  le2: Orden le2 &lt;br /&gt;
    for le1 (infix &amp;quot;⊑⇩1&amp;quot; 50) and le2 (infix &amp;quot;⊑⇩2&amp;quot; 50) +&lt;br /&gt;
  fixes f :: &amp;quot;&amp;#039;a ⇒ &amp;#039;b&amp;quot;&lt;br /&gt;
  assumes mono: &amp;quot;x ⊑⇩1 y ⟹ f(x) ⊑⇩2 f(y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si f es monótona, x ⊑_1 y e y ⊑_1 z, entonces f(x) ⊑_2 f(z).&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in Mono) mono_trans: &lt;br /&gt;
  assumes &amp;quot;x ⊑⇩1 y&amp;quot; and &amp;quot;y ⊑⇩1 z&amp;quot; &lt;br /&gt;
  shows &amp;quot;f(x) ⊑⇩2 f(z)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⊑⇩1 z&amp;quot; using assms and le1.trans by blast&lt;br /&gt;
  then show &amp;quot;f(x) ⊑⇩2 f(z)&amp;quot; using mono by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El teorema generado se llama Mono.mono_trans.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm Mono.mono_trans&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En el contexto Mono el nombre es mono_trans.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
context Mono &lt;br /&gt;
begin &lt;br /&gt;
thm mono_trans &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El predicado `ser par&amp;#039; es un operador monótono entre los naturales con la&lt;br /&gt;
  relación de divisibilidad y los booleanos con el condicional; es decir, &lt;br /&gt;
     x dvd y ⟹ even x ⟶ even y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Mono &amp;quot;(dvd)&amp;quot; &amp;quot;(⟶)&amp;quot; &amp;quot;λn::nat. 2 dvd n&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix x y :: nat &lt;br /&gt;
  show &amp;quot;x dvd y ⟹ even x ⟶ even y&amp;quot;&lt;br /&gt;
    proof &lt;br /&gt;
      assume &amp;quot;x dvd y&amp;quot; and &amp;quot;even x&amp;quot;&lt;br /&gt;
      then show &amp;quot;even y&amp;quot; &lt;br /&gt;
        using  Rings.comm_monoid_mult_class.dvd_trans by auto&lt;br /&gt;
    qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Semigrupos, monoides y grupos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definición de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un semigrupo es una estructura compuesta por un conjunto A y una&lt;br /&gt;
  operación binaria en A.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class semigrupo =&lt;br /&gt;
  fixes mult :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⊗&amp;quot; 70) &lt;br /&gt;
  assumes asoc: &amp;quot;(x ⊗ y) ⊗ z = x ⊗ (y ⊗ z )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Instanciación de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los enteros con la suma forman un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation int :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
definition &lt;br /&gt;
  mult_int_def: &amp;quot;i ⊗ j = i + (j ::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i j k :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;(i + j ) + k = i + (j + k)&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;(i ⊗ j ) ⊗ k = i ⊗ (j ⊗ k)&amp;quot; unfolding mult_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales con la suma forman un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
primrec mult_nat where &lt;br /&gt;
  &amp;quot;(0::nat) ⊗ n = n&amp;quot; &lt;br /&gt;
| &amp;quot;Suc m ⊗ n = Suc (m ⊗ n)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix m n q :: &amp;quot;nat&amp;quot; &lt;br /&gt;
  show &amp;quot;m ⊗ n ⊗ q = m ⊗ (n ⊗ q)&amp;quot; &lt;br /&gt;
    by (induct m) auto&lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Instancias recursivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si (A,⊗) y (B,⊗) son semigrupos, entonces ((A×B,⊗), donde el producto&lt;br /&gt;
  se define por &lt;br /&gt;
     (x,y)⊗(x&amp;#039;,y&amp;#039;) = (x⊗x&amp;#039;,y⊗y&amp;#039;),&lt;br /&gt;
  es un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
 &lt;br /&gt;
instantiation prod :: (semigrupo, semigrupo) semigrupo &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  mult_prod_def : &amp;quot;p1 ⊗ p2 = (fst p1 ⊗ fst p2, snd p1 ⊗ snd p2)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p1 p2 p3 :: &amp;quot;&amp;#039;a::semigrupo × &amp;#039;b::semigrupo&amp;quot; &lt;br /&gt;
  show &amp;quot;(p1 ⊗ p2) ⊗ p3 = p1 ⊗ (p2 ⊗ p3)&amp;quot; &lt;br /&gt;
    unfolding mult_prod_def by (simp add: asoc) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Subclases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un monoide izquierdo es un semigrupo con elemento neutro por la izquierda. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class monoideI = semigrupo + &lt;br /&gt;
  fixes neutro :: &amp;quot;&amp;#039;a&amp;quot; (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
  assumes neutroI: &amp;quot;𝟭 ⊗ x = x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales y los enteros con la suma forman monoides por la izquierda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_nat_def : &amp;quot;𝟭 = (0::nat)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_int_def : &amp;quot;𝟭 = (0::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ n = n&amp;quot; unfolding neutro_nat_def by simp&lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ k = k&amp;quot; unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos monoides por la izquierda es un monoide por la&lt;br /&gt;
  izquierda, donde el neutro es el par formado por los elementos neutros.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoideI , monoideI) monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_prod_def : &amp;quot;𝟭 = (𝟭, 𝟭)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoideI × &amp;#039;b::monoideI&amp;quot; &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ p = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutroI) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un monoide es un monoide por la izquierda cuyo elemento neutro por la&lt;br /&gt;
  izquierda lo es también por la derecha.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class monoide = monoideI + &lt;br /&gt;
  assumes neutro: &amp;quot;x ⊗ 𝟭 = x&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales y los enteros con la suma son monoides.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;n ⊗ 𝟭 = n&amp;quot; &lt;br /&gt;
    unfolding neutro_nat_def by (induct n) simp_all &lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;k ⊗ 𝟭 = k&amp;quot; &lt;br /&gt;
    unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos monoides es un monoide.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoide, monoide) monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoide × &amp;#039;b::monoide&amp;quot; &lt;br /&gt;
  show &amp;quot;p ⊗ 𝟭 = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutro) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un grupo es un monoide por la izquierda tal que todo elemento posee un&lt;br /&gt;
  inverso por la izquierda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class grupo2 = monoideI + &lt;br /&gt;
  fixes inverso :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a&amp;quot; (&amp;quot;(_⇧-⇧1)&amp;quot; [1000] 999)&lt;br /&gt;
  assumes inversoI: &amp;quot;x⇧-⇧1 ⊗ x = 𝟭&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los enteros con la suma forman un grupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation int :: grupo2 &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition&lt;br /&gt;
  inverso_int_def: &amp;quot;i⇧-⇧1 = -(i::int)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;-i + i = 0&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;i⇧-⇧1 ⊗ i = 𝟭&amp;quot; &lt;br /&gt;
    unfolding mult_int_def neutro_int_def inverso_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Razonamiento abstracto *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los grupos se verifica la propiedad cancelativa por la izquierda, i.e.&lt;br /&gt;
     x ⊗ y = x ⊗ z ⟷ y = z&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in grupo2) cancelativa_izq: &amp;quot;x ⊗ y = x ⊗ z ⟷ y = z&amp;quot; &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;x ⊗ y = x ⊗ z&amp;quot;&lt;br /&gt;
  hence &amp;quot;x⇧-⇧1 ⊗ (x ⊗ y) = x⇧-⇧1 ⊗ (x ⊗ z)&amp;quot; by simp &lt;br /&gt;
  hence &amp;quot;(x⇧-⇧1 ⊗ x) ⊗ y = (x⇧-⇧1 ⊗ x) ⊗ z&amp;quot; using asoc by simp &lt;br /&gt;
  then show &amp;quot;y = z&amp;quot; using neutroI and inversoI by simp&lt;br /&gt;
next &lt;br /&gt;
  assume &amp;quot;y = z&amp;quot; &lt;br /&gt;
  then show &amp;quot;x ⊗ y = x ⊗ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
thm grupo2.cancelativa_izq&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se genera el teorema grupo.cancelativa_izq&lt;br /&gt;
     class.grupo2 ?mult ?neutro ?inverso ⟹ &lt;br /&gt;
     (?mult ?x ?y = ?mult ?x ?z) = (?y = ?z)&lt;br /&gt;
&lt;br /&gt;
  El teorema se aplica automáticamente a todas las instancias de la clase&lt;br /&gt;
  grupo. Por ejemplo, a los enteros.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definiciones derivadas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los monoides se define la potencia natural por&lt;br /&gt;
  · x^0     = 1&lt;br /&gt;
  · x^{n+1} = x*x^n&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun (in monoide) potencia_nat :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_nat 0 x       = 𝟭&amp;quot;  &lt;br /&gt;
| &amp;quot;potencia_nat (Suc n) x = x ⊗ potencia_nat n x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Analogía entre clases y functores *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;⋀x y z. (x @ y) @ z = x @ (y @ z)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. [] @ x = x&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. x @ [] = x&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se pueden aplicar propiedades de los monides a las listas. Por ejemplo,&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;append [] xs = xs&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  (repite n xs) es la lista obtenida concatenando n veces la lista xs. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where &lt;br /&gt;
  &amp;quot;repite 0 _        = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) xs = xs @ repite n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide. Además, la potencia natural se intepreta como&lt;br /&gt;
  repite. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; rewrites&lt;br /&gt;
  &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
proof -&lt;br /&gt;
  interpret monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; .. &lt;br /&gt;
  show &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
  proof &lt;br /&gt;
    fix n &lt;br /&gt;
    show &amp;quot;monoide.potencia_nat append [] n = repite n&amp;quot;&lt;br /&gt;
      by (induct n) auto &lt;br /&gt;
  qed &lt;br /&gt;
qed intro_locales&lt;br /&gt;
&lt;br /&gt;
subsection {* Relaciones de subclase adicionales *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los grupos son monoides.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subclass (in grupo2) monoide &lt;br /&gt;
proof &lt;br /&gt;
  fix x &lt;br /&gt;
  have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ (x ⊗ (x⇧-⇧1 ⊗ x))&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = (x⇧-⇧1 ⊗ x) ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; using asoc [symmetric] by simp&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = x⇧-⇧1 ⊗ x&amp;quot; using neutroI by simp&lt;br /&gt;
  finally have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ x&amp;quot; . &lt;br /&gt;
  then show &amp;quot;x ⊗ 𝟭 = x&amp;quot; using cancelativa_izq by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La potencia entera en los grupos se define a partir de la potencia natural&lt;br /&gt;
  como sigue:&lt;br /&gt;
  · x^k = x^k si k ≥ 0&lt;br /&gt;
  · x^k = (x^{-k})^{-1}, en caso contrario.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition (in grupo2) potencia_entera :: &amp;quot;int ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_entera k x = &lt;br /&gt;
   (if k &amp;gt;= 0 &lt;br /&gt;
    then potencia_nat (nat k) x &lt;br /&gt;
    else (potencia_nat (nat (- k)) x)⇧-⇧1)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
section {* Bibliografía *}&lt;br /&gt;
text {* &lt;br /&gt;
  + &amp;quot;Haskell-style type classes with Isabelle/Isar&amp;quot; ~ F. Haftmann.&lt;br /&gt;
    http://bit.ly/2E55pAJ&lt;br /&gt;
  + &amp;quot;Tutorial to locales and locale interpretation&amp;quot; ~ C. Ballarin.&lt;br /&gt;
    http://bit.ly/2E3ozXB  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=825</id>
		<title>Razonamiento sobre árboles y bosques</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=825"/>
		<updated>2020-05-14T06:02:22Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 8: Razonamiento sobre árboles›&lt;br /&gt;
&lt;br /&gt;
theory T8_Razonamiento_sobre_arboles&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se estudia razonamiento sobre otras estructuras&lt;br /&gt;
  recursivas como árboles binarios, árboles generales y bosques.&lt;br /&gt;
  &lt;br /&gt;
  También se muestra cómo definir tipos de datos por recursión cruzada y&lt;br /&gt;
  la demostración de sus propiedades por inducción.›&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento sobre árboles binarios›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición de tipos recursivos:&lt;br /&gt;
  Definir un tipo de dato para los árboles binarios.›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbolB = Hoja &amp;quot;&amp;#039;a&amp;quot; &lt;br /&gt;
                   | Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Regla de inducción correspondiente a los árboles binarios:&lt;br /&gt;
  La regla de inducción sobre árboles binarios es arbol.induct:&lt;br /&gt;
  ⟦ ⋀x. P (Hoja x);&lt;br /&gt;
    ⋀x i d. ⟦P i; P d⟧ ⟹ P (Nodo x i d)⟧ &lt;br /&gt;
  ⟹ P a&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm arbolB.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición sobre árboles binarios:&lt;br /&gt;
  Definir la función &amp;quot;espejo&amp;quot; que aplicada a un árbol devuelve su imagen&lt;br /&gt;
  especular.›&lt;br /&gt;
&lt;br /&gt;
fun espejo :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a arbolB&amp;quot; where&lt;br /&gt;
  &amp;quot;espejo (Hoja x)     = Hoja x&amp;quot;&lt;br /&gt;
| &amp;quot;espejo (Nodo x i d) = Nodo x (espejo d) (espejo i)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;espejo (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      Nodo a (Hoja e) (Nodo b (Hoja d) (Hoja c))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración sobre árboles binarios:&lt;br /&gt;
  Demostrar que la función &amp;quot;espejo&amp;quot; es involutiva; es decir, para&lt;br /&gt;
  cualquier árbol a, se tiene que &lt;br /&gt;
     espejo (espejo a) = a.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot;  by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; &lt;br /&gt;
      using h1 h2 by simp &lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa detallada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot;  &lt;br /&gt;
    by (simp only: espejo.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; &lt;br /&gt;
      by (simp only: h1 h2) &lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;) es una abreviatura de &amp;quot;sea a1 un árbol binario&lt;br /&gt;
    cuyos elementos son de tipo b&amp;quot;. &lt;br /&gt;
  · (induct a) indica que el método de demostración es por inducción&lt;br /&gt;
    en el árbol binario a.&lt;br /&gt;
  · Se generan dos casos:&lt;br /&gt;
    1. ⋀a. espejo (espejo (Hoja a)) = Hoja a&lt;br /&gt;
    2. ⋀a1 a2 a3. ⟦espejo (espejo a2) = a2; &lt;br /&gt;
                   espejo (espejo a3) = a3⟧&lt;br /&gt;
                  ⟹ espejo (espejo (Nodo a1 a2 a3)) = Nodo a1 a2 a3›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: espejo.simps(1))&lt;br /&gt;
  apply (simp only: espejo.simps(2))&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  by (induct a) simp+ &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática detallada es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  by (induct a) (simp only: espejo.simps)+  &lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo. [Aplanamiento de árboles]&lt;br /&gt;
  Definir la función &amp;quot;aplana&amp;quot; que aplane los árboles recorriéndolos en&lt;br /&gt;
  orden infijo.›&lt;br /&gt;
&lt;br /&gt;
fun aplana :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana (Hoja x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;aplana (Nodo x i d) = aplana i @ [x] @ aplana d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;aplana (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      [c, b, d, a, e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo. [Aplanamiento de la imagen especular] Demostrar que&lt;br /&gt;
     aplana (espejo a) = rev (aplana a)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x &lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      using h1 h2 by simp&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Lema auxiliar para la demostración declarativa detallada›&lt;br /&gt;
lemma rev_unit: &amp;quot;rev [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;rev [x] = rev [] @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: rev.simps(2))&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot;&lt;br /&gt;
    by (simp only: rev.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot;&lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  finally show ?thesis&lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada y detallada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x :: &amp;#039;b&lt;br /&gt;
  have &amp;quot;aplana (espejo (Hoja x)) = aplana (Hoja x)&amp;quot;&lt;br /&gt;
    by (simp only: espejo.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot;&lt;br /&gt;
    by (simp only: aplana.simps(1))&lt;br /&gt;
  also have &amp;quot;… = rev [x]&amp;quot;&lt;br /&gt;
    by (simp only: rev_unit)&lt;br /&gt;
  also have &amp;quot;… = rev (aplana (Hoja x))&amp;quot;&lt;br /&gt;
    by (simp only: aplana.simps(1))&lt;br /&gt;
  finally show &amp;quot;?P (Hoja x)&amp;quot; &lt;br /&gt;
    by this &lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;b&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: aplana.simps(2))&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      by (simp only: h1 h2)&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; &lt;br /&gt;
      by (simp only: rev_append rev_unit append_assoc)&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; &lt;br /&gt;
      by (simp only: aplana.simps(2))&lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: espejo.simps(1) aplana.simps(1))&lt;br /&gt;
   apply (simp only: rev_unit)&lt;br /&gt;
  apply (simp only: espejo.simps(2) aplana.simps(2))&lt;br /&gt;
  apply (simp only: rev_append)&lt;br /&gt;
  apply (simp only: rev_unit)&lt;br /&gt;
  apply (simp only: append_assoc)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada compacta es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: &lt;br /&gt;
      espejo.simps(1) &lt;br /&gt;
      aplana.simps(1)&lt;br /&gt;
      rev_unit&lt;br /&gt;
      espejo.simps(2) &lt;br /&gt;
      aplana.simps(2)&lt;br /&gt;
      rev_append&lt;br /&gt;
      append_assoc)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada más compacta es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: &lt;br /&gt;
      espejo.simps&lt;br /&gt;
      aplana.simps&lt;br /&gt;
      rev_unit&lt;br /&gt;
      rev_append&lt;br /&gt;
      append_assoc)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática detallada es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  by (induct a)&lt;br /&gt;
     (simp only: &lt;br /&gt;
      espejo.simps&lt;br /&gt;
      aplana.simps&lt;br /&gt;
      rev_unit&lt;br /&gt;
      rev_append&lt;br /&gt;
      append_assoc)+&lt;br /&gt;
&lt;br /&gt;
section ‹Árboles y bosques. Recursión mutua e inducción›&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Ejemplo de definición de tipos mediante recursión cruzada]&lt;br /&gt;
  · Un árbol de tipo a es una hoja o un nodo de tipo a junto con un&lt;br /&gt;
    bosque de tipo a.&lt;br /&gt;
  · Un bosque de tipo a es el boque vacío o un bosque contruido añadiendo&lt;br /&gt;
    un árbol de tipo a a un bosque de tipo a.›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
     and &amp;#039;a bosque = Vacio | ConsB &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Regla de inducción correspondiente a la recursión cruzada:&lt;br /&gt;
  La regla de inducción sobre árboles y bosques es arbol_bosque.induct:&lt;br /&gt;
     ⟦⋀x b. P2 b ⟹ P1 (Nodo x b); &lt;br /&gt;
      P2 Vacio;&lt;br /&gt;
      ⋀a b. ⟦P1 a; P2 b⟧ ⟹ P2 (ConsB a b)⟧ &lt;br /&gt;
     ⟹ P1 a ∧ P2 b›&lt;br /&gt;
&lt;br /&gt;
thm arbol_bosque.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplos de definición por recursión cruzada:&lt;br /&gt;
  · aplana_arbol a) es la lista obtenida aplanando el árbol a.   &lt;br /&gt;
  · (aplana_bosque b) es la lista obtenida aplanando el bosque b.   &lt;br /&gt;
  · (map_arbol f a) es el árbol obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del árbol a.   &lt;br /&gt;
  · (map_bosque f b) es el bosque obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del bosque b. ›&lt;br /&gt;
&lt;br /&gt;
fun aplana_arbol :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; and &lt;br /&gt;
    aplana_bosque :: &amp;quot;&amp;#039;a bosque ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana_arbol (Nodo x b)   = x # (aplana_bosque b)&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque Vacio       = []&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque (ConsB a b) = (aplana_arbol a) @ (aplana_bosque b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun map_arbol :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a arbol ⇒ &amp;#039;b arbol&amp;quot; and&lt;br /&gt;
    map_bosque :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a bosque ⇒ &amp;#039;b bosque&amp;quot; where&lt;br /&gt;
  &amp;quot;map_arbol  f (Nodo x b)  = Nodo (f x) (map_bosque f b)&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f Vacio       = Vacio&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f (ConsB a b) = ConsB (map_arbol f a) (map_bosque f b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por inducción cruzada:&lt;br /&gt;
  Demostrar que:&lt;br /&gt;
  · aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
  · aplana_bosque (map_bosque f b) = map f (aplana_bosque b)›&lt;br /&gt;
&lt;br /&gt;
declare [[names_short]] &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI1 HI2 by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) =&lt;br /&gt;
                map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: map_arbol.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: aplana_arbol.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    by (simp only: HI)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by (simp only: list.map aplana_arbol.simps(1))&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(1)&lt;br /&gt;
                   map_bosque.simps(1)&lt;br /&gt;
                   list.map)&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: map_bosque.simps(2))&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(2))&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    by (simp only: HI1 HI2)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol a @ aplana_bosque b)&amp;quot;&lt;br /&gt;
    by (simp only: map_append)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(2))&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) =&lt;br /&gt;
                map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct_tac a and b) indica que el método de demostración es por&lt;br /&gt;
    inducción cruzada sobre a y b.&lt;br /&gt;
  · Se generan 3 casos:&lt;br /&gt;
    1. ⋀a bosque.&lt;br /&gt;
          aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque) ⟹&lt;br /&gt;
          aplana_arbol (map_arbol (arbol.Nodo a bosque) h) =&lt;br /&gt;
          map h (aplana_arbol (arbol.Nodo a bosque))&lt;br /&gt;
    2. aplana_bosque (map_bosque Vacio h) = map h (aplana_bosque Vacio)&lt;br /&gt;
    3. ⋀arbol bosque.&lt;br /&gt;
          ⟦aplana_arbol (map_arbol arbol h) = map h (aplana_arbol arbol);&lt;br /&gt;
           aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque)⟧&lt;br /&gt;
          ⟹ aplana_bosque (map_bosque (ConsB arbol bosque) h) =&lt;br /&gt;
             map h (aplana_bosque (ConsB arbol bosque))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply simp&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply (simp only: map_arbol.simps aplana_arbol.simps)&lt;br /&gt;
    apply (simp only: list.map(2))&lt;br /&gt;
   apply (simp only: map_bosque.simps(1) aplana_bosque.simps(1))&lt;br /&gt;
   apply (simp only: list.map(1))&lt;br /&gt;
  apply (simp only: map_bosque.simps(2) aplana_bosque.simps(2))&lt;br /&gt;
  apply (simp only: map_append)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada compacta es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply (simp only: &lt;br /&gt;
      map_arbol.simps &lt;br /&gt;
      aplana_arbol.simps&lt;br /&gt;
      list.map(2)&lt;br /&gt;
      map_bosque.simps(1) &lt;br /&gt;
      aplana_bosque.simps(1)&lt;br /&gt;
      list.map(1)&lt;br /&gt;
      map_bosque.simps(2) &lt;br /&gt;
      aplana_bosque.simps(2)&lt;br /&gt;
      map_append)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada más compacta es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply (simp only: &lt;br /&gt;
      map_arbol.simps &lt;br /&gt;
      map_bosque.simps&lt;br /&gt;
      aplana_arbol.simps&lt;br /&gt;
      aplana_bosque.simps&lt;br /&gt;
      list.map&lt;br /&gt;
      map_append)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  by (induct_tac a and b) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  by (induct_tac a and b) &lt;br /&gt;
     (simp only: &lt;br /&gt;
      map_arbol.simps &lt;br /&gt;
      map_bosque.simps&lt;br /&gt;
      aplana_arbol.simps&lt;br /&gt;
      aplana_bosque.simps&lt;br /&gt;
      list.map&lt;br /&gt;
      map_append)+&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=824</id>
		<title>Razonamiento sobre árboles y bosques</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=824"/>
		<updated>2020-05-14T06:00:37Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 8: Razonamiento sobre árboles›&lt;br /&gt;
&lt;br /&gt;
theory T8_Razonamiento_sobre_arboles&lt;br /&gt;
imports Main HOL.Parity&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se estudia razonamiento sobre otras estructuras&lt;br /&gt;
  recursivas como árboles binarios, árboles generales y bosques.&lt;br /&gt;
  &lt;br /&gt;
  También se muestra cómo definir tipos de datos por recursión cruzada y&lt;br /&gt;
  la demostración de sus propiedades por inducción.›&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento sobre árboles binarios›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición de tipos recursivos:&lt;br /&gt;
  Definir un tipo de dato para los árboles binarios.›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbolB = Hoja &amp;quot;&amp;#039;a&amp;quot; &lt;br /&gt;
                   | Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Regla de inducción correspondiente a los árboles binarios:&lt;br /&gt;
  La regla de inducción sobre árboles binarios es arbol.induct:&lt;br /&gt;
  ⟦ ⋀x. P (Hoja x);&lt;br /&gt;
    ⋀x i d. ⟦P i; P d⟧ ⟹ P (Nodo x i d)⟧ &lt;br /&gt;
  ⟹ P a&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm arbolB.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición sobre árboles binarios:&lt;br /&gt;
  Definir la función &amp;quot;espejo&amp;quot; que aplicada a un árbol devuelve su imagen&lt;br /&gt;
  especular.›&lt;br /&gt;
&lt;br /&gt;
fun espejo :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a arbolB&amp;quot; where&lt;br /&gt;
  &amp;quot;espejo (Hoja x)     = Hoja x&amp;quot;&lt;br /&gt;
| &amp;quot;espejo (Nodo x i d) = Nodo x (espejo d) (espejo i)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;espejo (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      Nodo a (Hoja e) (Nodo b (Hoja d) (Hoja c))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración sobre árboles binarios:&lt;br /&gt;
  Demostrar que la función &amp;quot;espejo&amp;quot; es involutiva; es decir, para&lt;br /&gt;
  cualquier árbol a, se tiene que &lt;br /&gt;
     espejo (espejo a) = a.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot;  by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; &lt;br /&gt;
      using h1 h2 by simp &lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa detallada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot;  &lt;br /&gt;
    by (simp only: espejo.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; &lt;br /&gt;
      by (simp only: h1 h2) &lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;) es una abreviatura de &amp;quot;sea a1 un árbol binario&lt;br /&gt;
    cuyos elementos son de tipo b&amp;quot;. &lt;br /&gt;
  · (induct a) indica que el método de demostración es por inducción&lt;br /&gt;
    en el árbol binario a.&lt;br /&gt;
  · Se generan dos casos:&lt;br /&gt;
    1. ⋀a. espejo (espejo (Hoja a)) = Hoja a&lt;br /&gt;
    2. ⋀a1 a2 a3. ⟦espejo (espejo a2) = a2; &lt;br /&gt;
                   espejo (espejo a3) = a3⟧&lt;br /&gt;
                  ⟹ espejo (espejo (Nodo a1 a2 a3)) = Nodo a1 a2 a3›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: espejo.simps(1))&lt;br /&gt;
  apply (simp only: espejo.simps(2))&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  by (induct a) simp+ &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática detallada es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  by (induct a) (simp only: espejo.simps)+  &lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo. [Aplanamiento de árboles]&lt;br /&gt;
  Definir la función &amp;quot;aplana&amp;quot; que aplane los árboles recorriéndolos en&lt;br /&gt;
  orden infijo.›&lt;br /&gt;
&lt;br /&gt;
fun aplana :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana (Hoja x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;aplana (Nodo x i d) = aplana i @ [x] @ aplana d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;aplana (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      [c, b, d, a, e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo. [Aplanamiento de la imagen especular] Demostrar que&lt;br /&gt;
     aplana (espejo a) = rev (aplana a)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x &lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      using h1 h2 by simp&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Lema auxiliar para la demostración declarativa detallada›&lt;br /&gt;
lemma rev_unit: &amp;quot;rev [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;rev [x] = rev [] @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: rev.simps(2))&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot;&lt;br /&gt;
    by (simp only: rev.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot;&lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  finally show ?thesis&lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada y detallada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x :: &amp;#039;b&lt;br /&gt;
  have &amp;quot;aplana (espejo (Hoja x)) = aplana (Hoja x)&amp;quot;&lt;br /&gt;
    by (simp only: espejo.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot;&lt;br /&gt;
    by (simp only: aplana.simps(1))&lt;br /&gt;
  also have &amp;quot;… = rev [x]&amp;quot;&lt;br /&gt;
    by (simp only: rev_unit)&lt;br /&gt;
  also have &amp;quot;… = rev (aplana (Hoja x))&amp;quot;&lt;br /&gt;
    by (simp only: aplana.simps(1))&lt;br /&gt;
  finally show &amp;quot;?P (Hoja x)&amp;quot; &lt;br /&gt;
    by this &lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;b&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: aplana.simps(2))&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      by (simp only: h1 h2)&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; &lt;br /&gt;
      by (simp only: rev_append rev_unit append_assoc)&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; &lt;br /&gt;
      by (simp only: aplana.simps(2))&lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: espejo.simps(1) aplana.simps(1))&lt;br /&gt;
   apply (simp only: rev_unit)&lt;br /&gt;
  apply (simp only: espejo.simps(2) aplana.simps(2))&lt;br /&gt;
  apply (simp only: rev_append)&lt;br /&gt;
  apply (simp only: rev_unit)&lt;br /&gt;
  apply (simp only: append_assoc)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada compacta es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: &lt;br /&gt;
      espejo.simps(1) &lt;br /&gt;
      aplana.simps(1)&lt;br /&gt;
      rev_unit&lt;br /&gt;
      espejo.simps(2) &lt;br /&gt;
      aplana.simps(2)&lt;br /&gt;
      rev_append&lt;br /&gt;
      append_assoc)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada más compacta es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply (simp only: &lt;br /&gt;
      espejo.simps&lt;br /&gt;
      aplana.simps&lt;br /&gt;
      rev_unit&lt;br /&gt;
      rev_append&lt;br /&gt;
      append_assoc)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática detallada es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  by (induct a)&lt;br /&gt;
     (simp only: &lt;br /&gt;
      espejo.simps&lt;br /&gt;
      aplana.simps&lt;br /&gt;
      rev_unit&lt;br /&gt;
      rev_append&lt;br /&gt;
      append_assoc)+&lt;br /&gt;
&lt;br /&gt;
section ‹Árboles y bosques. Recursión mutua e inducción›&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Ejemplo de definición de tipos mediante recursión cruzada]&lt;br /&gt;
  · Un árbol de tipo a es una hoja o un nodo de tipo a junto con un&lt;br /&gt;
    bosque de tipo a.&lt;br /&gt;
  · Un bosque de tipo a es el boque vacío o un bosque contruido añadiendo&lt;br /&gt;
    un árbol de tipo a a un bosque de tipo a.›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
     and &amp;#039;a bosque = Vacio | ConsB &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Regla de inducción correspondiente a la recursión cruzada:&lt;br /&gt;
  La regla de inducción sobre árboles y bosques es arbol_bosque.induct:&lt;br /&gt;
     ⟦⋀x b. P2 b ⟹ P1 (Nodo x b); &lt;br /&gt;
      P2 Vacio;&lt;br /&gt;
      ⋀a b. ⟦P1 a; P2 b⟧ ⟹ P2 (ConsB a b)⟧ &lt;br /&gt;
     ⟹ P1 a ∧ P2 b›&lt;br /&gt;
&lt;br /&gt;
thm arbol_bosque.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplos de definición por recursión cruzada:&lt;br /&gt;
  · aplana_arbol a) es la lista obtenida aplanando el árbol a.   &lt;br /&gt;
  · (aplana_bosque b) es la lista obtenida aplanando el bosque b.   &lt;br /&gt;
  · (map_arbol f a) es el árbol obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del árbol a.   &lt;br /&gt;
  · (map_bosque f b) es el bosque obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del bosque b. ›&lt;br /&gt;
&lt;br /&gt;
fun aplana_arbol :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; and &lt;br /&gt;
    aplana_bosque :: &amp;quot;&amp;#039;a bosque ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana_arbol (Nodo x b)   = x # (aplana_bosque b)&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque Vacio       = []&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque (ConsB a b) = (aplana_arbol a) @ (aplana_bosque b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun map_arbol :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a arbol ⇒ &amp;#039;b arbol&amp;quot; and&lt;br /&gt;
    map_bosque :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a bosque ⇒ &amp;#039;b bosque&amp;quot; where&lt;br /&gt;
  &amp;quot;map_arbol  f (Nodo x b)  = Nodo (f x) (map_bosque f b)&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f Vacio       = Vacio&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f (ConsB a b) = ConsB (map_arbol f a) (map_bosque f b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por inducción cruzada:&lt;br /&gt;
  Demostrar que:&lt;br /&gt;
  · aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
  · aplana_bosque (map_bosque f b) = map f (aplana_bosque b)›&lt;br /&gt;
&lt;br /&gt;
declare [[names_short]] &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI1 HI2 by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) =&lt;br /&gt;
                map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: map_arbol.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: aplana_arbol.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    by (simp only: HI)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by (simp only: list.map aplana_arbol.simps(1))&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(1)&lt;br /&gt;
                   map_bosque.simps(1)&lt;br /&gt;
                   list.map)&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: map_bosque.simps(2))&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(2))&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    by (simp only: HI1 HI2)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol a @ aplana_bosque b)&amp;quot;&lt;br /&gt;
    by (simp only: map_append)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(2))&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) =&lt;br /&gt;
                map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct_tac a and b) indica que el método de demostración es por&lt;br /&gt;
    inducción cruzada sobre a y b.&lt;br /&gt;
  · Se generan 3 casos:&lt;br /&gt;
    1. ⋀a bosque.&lt;br /&gt;
          aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque) ⟹&lt;br /&gt;
          aplana_arbol (map_arbol (arbol.Nodo a bosque) h) =&lt;br /&gt;
          map h (aplana_arbol (arbol.Nodo a bosque))&lt;br /&gt;
    2. aplana_bosque (map_bosque Vacio h) = map h (aplana_bosque Vacio)&lt;br /&gt;
    3. ⋀arbol bosque.&lt;br /&gt;
          ⟦aplana_arbol (map_arbol arbol h) = map h (aplana_arbol arbol);&lt;br /&gt;
           aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque)⟧&lt;br /&gt;
          ⟹ aplana_bosque (map_bosque (ConsB arbol bosque) h) =&lt;br /&gt;
             map h (aplana_bosque (ConsB arbol bosque))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply simp&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply (simp only: map_arbol.simps aplana_arbol.simps)&lt;br /&gt;
    apply (simp only: list.map(2))&lt;br /&gt;
   apply (simp only: map_bosque.simps(1) aplana_bosque.simps(1))&lt;br /&gt;
   apply (simp only: list.map(1))&lt;br /&gt;
  apply (simp only: map_bosque.simps(2) aplana_bosque.simps(2))&lt;br /&gt;
  apply (simp only: map_append)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada compacta es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply (simp only: &lt;br /&gt;
      map_arbol.simps &lt;br /&gt;
      aplana_arbol.simps&lt;br /&gt;
      list.map(2)&lt;br /&gt;
      map_bosque.simps(1) &lt;br /&gt;
      aplana_bosque.simps(1)&lt;br /&gt;
      list.map(1)&lt;br /&gt;
      map_bosque.simps(2) &lt;br /&gt;
      aplana_bosque.simps(2)&lt;br /&gt;
      map_append)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa detallada más compacta es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
    apply (simp only: &lt;br /&gt;
      map_arbol.simps &lt;br /&gt;
      map_bosque.simps&lt;br /&gt;
      aplana_arbol.simps&lt;br /&gt;
      aplana_bosque.simps&lt;br /&gt;
      list.map&lt;br /&gt;
      map_append)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  by (induct_tac a and b) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  by (induct_tac a and b) &lt;br /&gt;
     (simp only: &lt;br /&gt;
      map_arbol.simps &lt;br /&gt;
      map_bosque.simps&lt;br /&gt;
      aplana_arbol.simps&lt;br /&gt;
      aplana_bosque.simps&lt;br /&gt;
      list.map&lt;br /&gt;
      map_append)+&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=823</id>
		<title>Razonamiento sobre árboles y bosques</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=823"/>
		<updated>2020-05-13T17:46:33Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 8: Razonamiento sobre árboles›&lt;br /&gt;
&lt;br /&gt;
theory T8_Razonamiento_sobre_arboles&lt;br /&gt;
imports Main HOL.Parity&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se estudia razonamiento sobre otras estructuras&lt;br /&gt;
  recursivas como árboles binarios, árboles generales y bosques.&lt;br /&gt;
  &lt;br /&gt;
  También se muestra cómo definir tipos de datos por recursión cruzada y&lt;br /&gt;
  la demostración de sus propiedades por inducción.›&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento sobre árboles binarios›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición de tipos recursivos:&lt;br /&gt;
  Definir un tipo de dato para los árboles binarios.›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbolB = Hoja &amp;quot;&amp;#039;a&amp;quot; &lt;br /&gt;
                   | Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Regla de inducción correspondiente a los árboles binarios:&lt;br /&gt;
  La regla de inducción sobre árboles binarios es arbol.induct:&lt;br /&gt;
  ⟦ ⋀x. P (Hoja x);&lt;br /&gt;
    ⋀x i d. ⟦P i; P d⟧ ⟹ P (Nodo x i d)⟧ &lt;br /&gt;
  ⟹ P a&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm arbolB.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición sobre árboles binarios:&lt;br /&gt;
  Definir la función &amp;quot;espejo&amp;quot; que aplicada a un árbol devuelve su imagen&lt;br /&gt;
  especular.›&lt;br /&gt;
&lt;br /&gt;
fun espejo :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a arbolB&amp;quot; where&lt;br /&gt;
  &amp;quot;espejo (Hoja x)     = Hoja x&amp;quot;&lt;br /&gt;
| &amp;quot;espejo (Nodo x i d) = Nodo x (espejo d) (espejo i)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;espejo (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      Nodo a (Hoja e) (Nodo b (Hoja d) (Hoja c))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración sobre árboles binarios:&lt;br /&gt;
  Demostrar que la función &amp;quot;espejo&amp;quot; es involutiva; es decir, para&lt;br /&gt;
  cualquier árbol a, se tiene que &lt;br /&gt;
     espejo (espejo a) = a.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot;  by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; &lt;br /&gt;
      using h1 h2 by simp &lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa detallada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot;  &lt;br /&gt;
    by (simp only: espejo.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; &lt;br /&gt;
      by (simp only: h1 h2) &lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;) es una abreviatura de &amp;quot;sea a1 un árbol binario&lt;br /&gt;
    cuyos elementos son de tipo b&amp;quot;. &lt;br /&gt;
  · (induct a) indica que el método de demostración es por inducción&lt;br /&gt;
    en el árbol binario a.&lt;br /&gt;
  · Se generan dos casos:&lt;br /&gt;
    1. ⋀a. espejo (espejo (Hoja a)) = Hoja a&lt;br /&gt;
    2. ⋀a1 a2 a3. ⟦espejo (espejo a2) = a2; &lt;br /&gt;
                   espejo (espejo a3) = a3⟧&lt;br /&gt;
                  ⟹ espejo (espejo (Nodo a1 a2 a3)) = Nodo a1 a2 a3›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma  &lt;br /&gt;
  &amp;quot;espejo (espejo a) = a&amp;quot;&lt;br /&gt;
  by (induct a) simp_all  &lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo. [Aplanamiento de árboles]&lt;br /&gt;
  Definir la función &amp;quot;aplana&amp;quot; que aplane los árboles recorriéndolos en&lt;br /&gt;
  orden infijo.›&lt;br /&gt;
&lt;br /&gt;
fun aplana :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana (Hoja x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;aplana (Nodo x i d) = aplana i @ [x] @ aplana d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;aplana (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      [c, b, d, a, e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo. [Aplanamiento de la imagen especular] Demostrar que&lt;br /&gt;
     aplana (espejo a) = rev (aplana a)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x &lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      using h1 h2 by simp&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Lema auxiliar para la demostración declarativa detallada›&lt;br /&gt;
lemma rev_unit: &amp;quot;rev [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;rev [x] = rev [] @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: rev.simps(2))&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot;&lt;br /&gt;
    by (simp only: rev.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot;&lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  finally show ?thesis&lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada y detallada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x :: &amp;#039;b&lt;br /&gt;
  have &amp;quot;aplana (espejo (Hoja x)) = aplana (Hoja x)&amp;quot;&lt;br /&gt;
    by (simp only: espejo.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot;&lt;br /&gt;
    by (simp only: aplana.simps(1))&lt;br /&gt;
  also have &amp;quot;… = rev [x]&amp;quot;&lt;br /&gt;
    by (simp only: rev_unit)&lt;br /&gt;
  also have &amp;quot;… = rev (aplana (Hoja x))&amp;quot;&lt;br /&gt;
    by (simp only: aplana.simps(1))&lt;br /&gt;
  finally show &amp;quot;?P (Hoja x)&amp;quot; &lt;br /&gt;
    by this &lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;b&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: espejo.simps(2))&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by (simp only: aplana.simps(2))&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      by (simp only: h1 h2)&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; &lt;br /&gt;
      by (simp only: rev_append rev_unit append_assoc)&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; &lt;br /&gt;
      by (simp only: aplana.simps(2))&lt;br /&gt;
    finally show ?thesis &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
section ‹Árboles y bosques. Recursión mutua e inducción›&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Ejemplo de definición de tipos mediante recursión cruzada]&lt;br /&gt;
  · Un árbol de tipo a es una hoja o un nodo de tipo a junto con un&lt;br /&gt;
    bosque de tipo a.&lt;br /&gt;
  · Un bosque de tipo a es el boque vacío o un bosque contruido añadiendo&lt;br /&gt;
    un árbol de tipo a a un bosque de tipo a.›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
     and &amp;#039;a bosque = Vacio | ConsB &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Regla de inducción correspondiente a la recursión cruzada:&lt;br /&gt;
  La regla de inducción sobre árboles y bosques es arbol_bosque.induct:&lt;br /&gt;
     ⟦⋀x b. P2 b ⟹ P1 (Nodo x b); &lt;br /&gt;
      P2 Vacio;&lt;br /&gt;
      ⋀a b. ⟦P1 a; P2 b⟧ ⟹ P2 (ConsB a b)⟧ &lt;br /&gt;
     ⟹ P1 a ∧ P2 b›&lt;br /&gt;
&lt;br /&gt;
thm arbol_bosque.induct&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplos de definición por recursión cruzada:&lt;br /&gt;
  · aplana_arbol a) es la lista obtenida aplanando el árbol a.   &lt;br /&gt;
  · (aplana_bosque b) es la lista obtenida aplanando el bosque b.   &lt;br /&gt;
  · (map_arbol f a) es el árbol obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del árbol a.   &lt;br /&gt;
  · (map_bosque f b) es el bosque obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del bosque b. ›&lt;br /&gt;
&lt;br /&gt;
fun aplana_arbol :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; and &lt;br /&gt;
    aplana_bosque :: &amp;quot;&amp;#039;a bosque ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana_arbol (Nodo x b)   = x # (aplana_bosque b)&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque Vacio       = []&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque (ConsB a b) = (aplana_arbol a) @ (aplana_bosque b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun map_arbol :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a arbol ⇒ &amp;#039;b arbol&amp;quot; and&lt;br /&gt;
    map_bosque :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a bosque ⇒ &amp;#039;b bosque&amp;quot; where&lt;br /&gt;
  &amp;quot;map_arbol  f (Nodo x b)  = Nodo (f x) (map_bosque f b)&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f Vacio       = Vacio&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f (ConsB a b) = ConsB (map_arbol f a) (map_bosque f b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por inducción cruzada:&lt;br /&gt;
  Demostrar que:&lt;br /&gt;
  · aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
  · aplana_bosque (map_bosque f b) = map f (aplana_bosque b)›&lt;br /&gt;
&lt;br /&gt;
declare [[names_short]] &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI1 HI2 by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) =&lt;br /&gt;
                map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: map_arbol.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: aplana_arbol.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    by (simp only: HI)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by (simp only: list.map aplana_arbol.simps(1))&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(1)&lt;br /&gt;
                   map_bosque.simps(1)&lt;br /&gt;
                   list.map)&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; &lt;br /&gt;
    by (simp only: map_bosque.simps(2))&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(2))&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    by (simp only: HI1 HI2)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol a @ aplana_bosque b)&amp;quot;&lt;br /&gt;
    by (simp only: map_append)&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by (simp only: aplana_bosque.simps(2))&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) =&lt;br /&gt;
                map f (aplana_bosque (ConsB a b))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct_tac a and b) indica que el método de demostración es por&lt;br /&gt;
    inducción cruzada sobre a y b.&lt;br /&gt;
  · Se generan 3 casos:&lt;br /&gt;
    1. ⋀a bosque.&lt;br /&gt;
          aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque) ⟹&lt;br /&gt;
          aplana_arbol (map_arbol (arbol.Nodo a bosque) h) =&lt;br /&gt;
          map h (aplana_arbol (arbol.Nodo a bosque))&lt;br /&gt;
    2. aplana_bosque (map_bosque Vacio h) = map h (aplana_bosque Vacio)&lt;br /&gt;
    3. ⋀arbol bosque.&lt;br /&gt;
          ⟦aplana_arbol (map_arbol arbol h) = map h (aplana_arbol arbol);&lt;br /&gt;
           aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque)⟧&lt;br /&gt;
          ⟹ aplana_bosque (map_bosque (ConsB arbol bosque) h) =&lt;br /&gt;
             map h (aplana_bosque (ConsB arbol bosque))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  by (induct_tac a and b) simp_all&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_por_casos_y_por_inducci%C2%A2n&amp;diff=822</id>
		<title>Razonamiento por casos y por inducci¢n</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_por_casos_y_por_inducci%C2%A2n&amp;diff=822"/>
		<updated>2020-05-06T17:00:20Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 7: Razonamiento por casos y por inducción›&lt;br /&gt;
&lt;br /&gt;
theory T7_Razonamiento_por_casos_y_por_induccion&lt;br /&gt;
imports Main HOL.Parity&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se amplían los métodos de demostración por casos y &lt;br /&gt;
  por inducción iniciados en el tema anterior.›&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por distinción de casos›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Distinción de casos booleanos›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por distinción de casos booleanos:&lt;br /&gt;
  Demostrar &amp;quot;¬A ∨ A&amp;quot;.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
proof cases&lt;br /&gt;
  assume &amp;quot;A&amp;quot; &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;¬A&amp;quot; &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios de la demostración anterior:&lt;br /&gt;
  · &amp;quot;proof cases&amp;quot; indica que el método de demostración será por&lt;br /&gt;
    distinción de casos. &lt;br /&gt;
  · Se generan 2 casos:&lt;br /&gt;
       1. ?P ⟹ ¬A ∨ A&lt;br /&gt;
       2. ¬?P ⟹ ¬A ∨ A&lt;br /&gt;
    donde ?P es una variable sobre las fórmulas.&lt;br /&gt;
  · (assume &amp;quot;A&amp;quot;) indica que se está usando &amp;quot;A&amp;quot; en lugar de la variable&lt;br /&gt;
    ?P.&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica usando la fórmula anterior.&lt;br /&gt;
  · &amp;quot;..&amp;quot; indica usando la regla lógica necesaria (las reglas lógicas se&lt;br /&gt;
    estudiarán en los siguientes temas).&lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente caso (se puede observar cómo ha&lt;br /&gt;
    sustituido ¬?P por ¬A.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply cases&lt;br /&gt;
   apply simp_all&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  by cases simp_all&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por distinción de casos booleanos con &lt;br /&gt;
  nombres: &lt;br /&gt;
  Demostrar &amp;quot;¬A ∨ A&amp;quot;.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
proof (cases &amp;quot;A&amp;quot;)&lt;br /&gt;
  case True &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  case False &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; .. &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (cases &amp;quot;A&amp;quot;) indica que la demostración se hará por casos según los&lt;br /&gt;
    distintos valores de &amp;quot;A&amp;quot;.&lt;br /&gt;
  · Como &amp;quot;A&amp;quot; es una fórmula, sus posibles valores son verdadero o falso.&lt;br /&gt;
  · &amp;quot;case True&amp;quot; indica que se está suponiendo que A es verdadera. Es&lt;br /&gt;
    equivalente a &amp;quot;assume A&amp;quot;.&lt;br /&gt;
  · &amp;quot;case False&amp;quot; indica que se está suponiendo que A es falsa. Es&lt;br /&gt;
    equivalente a &amp;quot;assume ¬A&amp;quot;.&lt;br /&gt;
  · En general, &lt;br /&gt;
    · el método (cases F) es una abreviatura de la aplicación de la regla&lt;br /&gt;
         ⟦F ⟹ Q; ¬F ⟹ Q⟧ ⟹ Q  &lt;br /&gt;
    · La expresión &amp;quot;case True&amp;quot; es una abreviatura de F.&lt;br /&gt;
    · La expresión &amp;quot;case False&amp;quot; es una abreviatura de ¬F.&lt;br /&gt;
  · Ventajas de &amp;quot;cases&amp;quot; con nombre: &lt;br /&gt;
    · reduce la escritura de la fórmula y&lt;br /&gt;
    · es independiente del orden de los casos.›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Distinción de casos sobre otros tipos de datos›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de distinción de casos sobre listas: &lt;br /&gt;
  Demostrar que la longitud del resto de una lista es la longitud de la&lt;br /&gt;
  lista menos 1.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then have &amp;quot;length (tl xs) = 0&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 0 - 1&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = length xs - 1&amp;quot;&lt;br /&gt;
    using ‹xs = []›&lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then have &amp;quot;length (tl xs) = length ys&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (1 + length ys) - 1&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = length (y#ys) - 1&amp;quot;&lt;br /&gt;
    by simp &lt;br /&gt;
  also have &amp;quot;… = length xs - 1&amp;quot;&lt;br /&gt;
    using ‹xs = y#ys›&lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; indica que la demostración se hará por casos sobre los&lt;br /&gt;
    posibles valores de xs.&lt;br /&gt;
  · Como xs es una lista, sus posibles valores son la lista vacía ([]) o&lt;br /&gt;
    una lista no vacía (de la forma (y#ys)).&lt;br /&gt;
  · Se generan 2 casos:&lt;br /&gt;
       1. xs = [] ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
       2. ⋀a list. xs = a # list ⟹ length (tl xs) = length xs - 1›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then have &amp;quot;length (tl xs) = 0&amp;quot;&lt;br /&gt;
    by (simp only: list.sel(2)&lt;br /&gt;
                   list.size(3))&lt;br /&gt;
  also have &amp;quot;… = 0 - 1&amp;quot;&lt;br /&gt;
    by (simp only: natural_zero_minus_one)&lt;br /&gt;
  also have &amp;quot;… = length xs - 1&amp;quot;&lt;br /&gt;
    using ‹xs = []›&lt;br /&gt;
    by (simp only: list.size(3))&lt;br /&gt;
  finally show &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then have &amp;quot;length (tl xs) = length ys&amp;quot;&lt;br /&gt;
    by (simp only: list.sel(3))&lt;br /&gt;
  also have &amp;quot;… = length (y#ys) - 1&amp;quot;&lt;br /&gt;
    by (simp only: length_Cons)&lt;br /&gt;
  also have &amp;quot;… = length xs - 1&amp;quot;&lt;br /&gt;
    using ‹xs = y#ys›&lt;br /&gt;
    by (simp only:)&lt;br /&gt;
  finally show &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración simplificada es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons &lt;br /&gt;
  then show ?thesis by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &lt;br /&gt;
       &amp;quot;assume xs =[]&amp;quot;.&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &lt;br /&gt;
       &amp;quot;fix y ys assume xs = y#ys&amp;quot;&lt;br /&gt;
  · ?thesis es una abreviatura de la conclusión del lema.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  apply (cases xs)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
text ‹En el siguiente ejemplo vamos a demostrar una propiedad de la &lt;br /&gt;
  función drop que está definida en la teoría List de forma que &lt;br /&gt;
  (drop n xs) es la lista obtenida eliminando en xs los n primeros &lt;br /&gt;
  elementos. Su definición es la siguiente   &lt;br /&gt;
     drop_Nil:  &amp;quot;drop n []     = []&amp;quot; &lt;br /&gt;
     drop_Cons: &amp;quot;drop n (x#xs) = (case n of &lt;br /&gt;
                                    0 =&amp;gt; x#xs | &lt;br /&gt;
                                    Suc(m) =&amp;gt; drop m xs)&amp;quot; ›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de análisis de casos:&lt;br /&gt;
  Demostrar que el resultado de eliminar los n+1 primeros elementos de&lt;br /&gt;
  xs es el mismo que eliminar los n primeros elementos del resto de xs.›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
  apply (cases xs)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
section ‹Inducción matemática›&lt;br /&gt;
&lt;br /&gt;
text ‹[Principio de inducción matemática]&lt;br /&gt;
  Para demostrar una propiedad P para todos los números naturales basta&lt;br /&gt;
  probar que el 0 tiene la propiedad P y que si n tiene la propiedad P,&lt;br /&gt;
  entonces n+1 también la tiene. &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción matemática está formalizado en&lt;br /&gt;
  el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por inducción: Usaremos el principio de&lt;br /&gt;
  inducción matemática para demostrar que &lt;br /&gt;
     1 + 3 + ... + (2n-1) = n^2&lt;br /&gt;
&lt;br /&gt;
  Definición. [Suma de los primeros impares] &lt;br /&gt;
  (suma_impares n) la suma de los n números impares. Por ejemplo,&lt;br /&gt;
     suma_impares 3  =  9&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
fun suma_impares :: &amp;quot;nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;suma_impares 0 = 0&amp;quot; &lt;br /&gt;
| &amp;quot;suma_impares (Suc n) = (2*(Suc n) - 1) + suma_impares n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;suma_impares 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹  Ejemplo de demostración por inducción matemática:&lt;br /&gt;
  Demostrar que la suma de los n primeros números impares es n^2.›&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración estructurada del lema anterior por inducción y &lt;br /&gt;
  razonamiento ecuacional›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;suma_impares 0 = 0 * 0&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n assume HI: &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  have &amp;quot;suma_impares (Suc n) = (2 * (Suc n) - 1) + suma_impares n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (2 * (Suc n) - 1) + n * n&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = n * n + 2 * n + 1&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (Suc n) * (Suc n)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;suma_impares (Suc n) = (Suc n) * (Suc n)&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración del lema anterior con patrones y razonamiento &lt;br /&gt;
   ecuacional›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;?P 0&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume HI: &amp;quot;?P n&amp;quot;&lt;br /&gt;
  have &amp;quot;suma_impares (Suc n) = (2 * (Suc n) - 1) + suma_impares n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (2 * (Suc n) - 1) + n * n&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = n * n + 2 * n + 1&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = Suc n * Suc n&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;?P (Suc n)&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentario sobre la demostración anterior:&lt;br /&gt;
  · Con la expresión&lt;br /&gt;
       &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
    se abrevia &amp;quot;suma_impares n = n * n&amp;quot; como &amp;quot;?P n&amp;quot;. Por tanto, &lt;br /&gt;
       &amp;quot;?P 0&amp;quot;       es una abreviatura de &amp;quot;suma_impares 0 = 0 * 0&amp;quot;&lt;br /&gt;
       &amp;quot;?P (Suc n)&amp;quot; es una abreviatura de &lt;br /&gt;
                    &amp;quot;suma_impares (Suc n) = (Suc n) * (Suc n)&amp;quot;&lt;br /&gt;
  · En general, cualquier fórmula seguida de (is patrón) equipara el&lt;br /&gt;
    patrón con la fórmula. ›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración usando patrones es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;?P 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;?P n&amp;quot;&lt;br /&gt;
  then show &amp;quot;?P (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
  &lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  apply (induct n)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de definición con existenciales. &lt;br /&gt;
  Un número natural n es par si existe un natural m tal que n=m+m.›&lt;br /&gt;
&lt;br /&gt;
definition par :: &amp;quot;nat ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;par n ≡ ∃m. n=m+m&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de inducción y existenciales: &lt;br /&gt;
  Demostrar que para todo número natural n, se verifica que n*(n+1) &lt;br /&gt;
  es par.›&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración estructurada por inducción›&lt;br /&gt;
lemma &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;par (0*(0+1))&amp;quot;&lt;br /&gt;
    by (simp add: par_def) &lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  then have &amp;quot;∃m. n*(n+1) = m+m&amp;quot; &lt;br /&gt;
    by (simp add: par_def)&lt;br /&gt;
  then obtain m where m: &amp;quot;n*(n+1) = m+m&amp;quot; &lt;br /&gt;
    by (rule exE)&lt;br /&gt;
  then have &amp;quot;(Suc n)*((Suc n)+1) = (m+n+1)+(m+n+1)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  then have &amp;quot;∃p. (Suc n)*((Suc n)+1) = p+p&amp;quot; &lt;br /&gt;
    by (rule exI)&lt;br /&gt;
  then show &amp;quot;par ((Suc n)*((Suc n)+1))&amp;quot; &lt;br /&gt;
    by (simp add: par_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración casi detallada por inducción›&lt;br /&gt;
lemma &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  have &amp;quot;(0::nat) = 0 + 0&amp;quot;&lt;br /&gt;
    by (simp only: add_0)&lt;br /&gt;
  then have &amp;quot;∃m. (0::nat) = m + m&amp;quot;&lt;br /&gt;
    by (rule exI)&lt;br /&gt;
  then have &amp;quot;par 0&amp;quot;&lt;br /&gt;
    by  (simp only: par_def)&lt;br /&gt;
  then show &amp;quot;par (0*(0+1))&amp;quot;&lt;br /&gt;
    by (simp only: mult_0) &lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  then have &amp;quot;∃m. n*(n+1) = m+m&amp;quot; &lt;br /&gt;
    by (simp only: par_def)&lt;br /&gt;
  then obtain m where m: &amp;quot;n*(n+1) = m+m&amp;quot; &lt;br /&gt;
    by (rule exE)&lt;br /&gt;
  then have &amp;quot;(Suc n)*((Suc n)+1) = (m+n+1)+(m+n+1)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  then have &amp;quot;∃p. (Suc n)*((Suc n)+1) = p+p&amp;quot; &lt;br /&gt;
    by (rule exI)&lt;br /&gt;
  then show &amp;quot;par ((Suc n)*((Suc n)+1))&amp;quot; &lt;br /&gt;
    by (simp only: par_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa por inducción›&lt;br /&gt;
lemma &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  apply (induct n)&lt;br /&gt;
   apply (simp add: par_def)&lt;br /&gt;
  apply (simp add: par_def)&lt;br /&gt;
  apply arith&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  by (induct n) (auto simp add: par_def, arith)&lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle puede demostrarse de manera más simple un lema&lt;br /&gt;
  equivalente usando en lugar de la función &amp;quot;par&amp;quot; la función &amp;quot;even&amp;quot; &lt;br /&gt;
  definida en la teoría Parity por&lt;br /&gt;
     even x ⟷ x mod 2 = 0 ›&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;even (n*(n+1))&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · Para poder usar la función &amp;quot;even&amp;quot; de la librería Parity es necesario&lt;br /&gt;
    importar dicha librería. Por ello, antes del inicio de la teoría&lt;br /&gt;
    aparece &lt;br /&gt;
       imports Main HOL.Parity &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹Para completar la demostración basta demostrar la equivalencia de &lt;br /&gt;
  las funciones &amp;quot;par&amp;quot; y &amp;quot;even&amp;quot;.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;par n = (∃m. n = m+m)&amp;quot; &lt;br /&gt;
    by (simp only: par_def)&lt;br /&gt;
  then show &amp;quot;par n = even n&amp;quot; &lt;br /&gt;
    (* try *) &lt;br /&gt;
    by presburger&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;by presburger&amp;quot; indica que se use como método de demostración el&lt;br /&gt;
    algoritmo de decisión de la aritmética de Presburger.›&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
  apply (unfold par_def)&lt;br /&gt;
  apply presburger&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
  by (simp only: par_def, presburger)&lt;br /&gt;
&lt;br /&gt;
section ‹Recursión general. La función de Ackermann›&lt;br /&gt;
&lt;br /&gt;
text ‹El objetivo de esta sección es mostrar el uso de las definiciones&lt;br /&gt;
  recursivas generales y sus esquemas de inducción. Como ejemplo se usa &lt;br /&gt;
  la función de Ackermann (se puede consultar información sobre dicha &lt;br /&gt;
  función en http://en.wikipedia.org/wiki/Ackermann_function).&lt;br /&gt;
&lt;br /&gt;
  Definición.  La función de Ackermann se define por&lt;br /&gt;
    A(m,n) = n+1,             si m=0,&lt;br /&gt;
             A(m-1,1),        si m&amp;gt;0 y n=0,&lt;br /&gt;
             A(m-1,A(m,n-1)), si m&amp;gt;0 y n&amp;gt;0&lt;br /&gt;
  para todo los números naturales. &lt;br /&gt;
&lt;br /&gt;
  La función de Ackermann es recursiva, pero no es primitiva recursiva.›&lt;br /&gt;
&lt;br /&gt;
fun ack :: &amp;quot;nat ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;ack 0       n       = n+1&amp;quot; &lt;br /&gt;
| &amp;quot;ack (Suc m) 0       = ack m 1&amp;quot; &lt;br /&gt;
| &amp;quot;ack (Suc m) (Suc n) = ack m (ack (Suc m) n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
― ‹Ejemplo de evaluación›&lt;br /&gt;
value &amp;quot;ack 2 3&amp;quot; (* devuelve 9 *)&lt;br /&gt;
&lt;br /&gt;
text ‹Esquema de inducción correspondiente a una función:&lt;br /&gt;
  · Al definir una función recursiva general se genera una regla de&lt;br /&gt;
    inducción. En la definición anterior, la regla generada es&lt;br /&gt;
    ack.induct: &lt;br /&gt;
       ⟦⋀n. P 0 n; &lt;br /&gt;
        ⋀m. P m 1 ⟹ P (Suc m) 0;&lt;br /&gt;
        ⋀m n. ⟦P (Suc m) n; P m (ack (Suc m) n)⟧ ⟹ P (Suc m) (Suc n)⟧&lt;br /&gt;
       ⟹ P a b&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo de demostración por la inducción correspondiente a una &lt;br /&gt;
  función:&lt;br /&gt;
  Demostrar que para todos m y n, A(m,n) &amp;gt; n.› &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
proof (induct m n rule: ack.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;ack 0 n &amp;gt; n&amp;quot; &lt;br /&gt;
    by (simp only: ack.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix m &lt;br /&gt;
  assume &amp;quot;ack m 1 &amp;gt; 1&amp;quot;&lt;br /&gt;
  then show &amp;quot;ack (Suc m) 0 &amp;gt; 0&amp;quot; &lt;br /&gt;
    by (simp only: ack.simps(2))&lt;br /&gt;
next  &lt;br /&gt;
  fix m n&lt;br /&gt;
  assume &amp;quot;n &amp;lt; ack (Suc m) n&amp;quot; &lt;br /&gt;
     and &amp;quot;ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)&amp;quot;&lt;br /&gt;
  then show &amp;quot;Suc n &amp;lt; ack (Suc m) (Suc n)&amp;quot; &lt;br /&gt;
    by (simp only: ack.simps(3))&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct m n rule: ack.induct) indica que el método de demostración&lt;br /&gt;
    es el esquema de recursión correspondiente a la definición de &lt;br /&gt;
    (ack m n).&lt;br /&gt;
  · Se generan 3 casos:&lt;br /&gt;
    1. ⋀n. n &amp;lt; ack 0 n&lt;br /&gt;
    2. ⋀m. 1 &amp;lt; ack m 1 ⟹ 0 &amp;lt; ack (Suc m) 0&lt;br /&gt;
    3. ⋀m n. ⟦n &amp;lt; ack (Suc m) n; &lt;br /&gt;
              ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)⟧&lt;br /&gt;
             ⟹ Suc n &amp;lt; ack (Suc m) (Suc n)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
  by (induct m n rule: ack.induct) auto&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=MediaWiki:Sidebar&amp;diff=821</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=MediaWiki:Sidebar&amp;diff=821"/>
		<updated>2020-04-25T18:26:17Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** Temas|Temas&lt;br /&gt;
** Ejercicios|Ejercicios&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* Ayudas&lt;br /&gt;
** https://es.wikipedia.org/wiki/Ayuda:Uso_de_TeX|Ayuda de LaTeX&lt;br /&gt;
** https://es.wikipedia.org/wiki/Ayuda:Uso_de_TeX#L%C3%B3gica|Lógica en LaTeX&lt;br /&gt;
** https://es.wikipedia.org/wiki/Ayuda:Uso_de_TeX#Conjuntos|Conjuntos en LaTeX&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=MediaWiki:Sidebar&amp;diff=820</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=MediaWiki:Sidebar&amp;diff=820"/>
		<updated>2020-04-25T18:25:34Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** Ejercicios|Ejercicios&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* Ayudas&lt;br /&gt;
** https://es.wikipedia.org/wiki/Ayuda:Uso_de_TeX|Ayuda de LaTeX&lt;br /&gt;
** https://es.wikipedia.org/wiki/Ayuda:Uso_de_TeX#L%C3%B3gica|Lógica en LaTeX&lt;br /&gt;
** https://es.wikipedia.org/wiki/Ayuda:Uso_de_TeX#Conjuntos|Conjuntos en LaTeX&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=819</id>
		<title>Razonamiento sobre programas en Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=819"/>
		<updated>2020-04-16T05:20:03Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 6: Razonamiento sobre programas›&lt;br /&gt;
&lt;br /&gt;
theory T6_Razonamiento_sobre_programas&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se demuestra con Isabelle las propiedades de los&lt;br /&gt;
  programas funcionales de tema 6 http://bit.ly/2Za6YWY&lt;br /&gt;
&lt;br /&gt;
  Para cada propiedades se presentan distintos tipos de demostraciones:&lt;br /&gt;
  automáticas, aplicativas y declarativas.› &lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento ecuacional›&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejemplo 1. Definir, por recursión, la función&lt;br /&gt;
     longitud :: &amp;#039;a list ⇒ nat&lt;br /&gt;
  tal que (longitud xs) es la longitud de la listas xs. Por ejemplo,&lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
fun longitud :: &amp;quot;&amp;#039;a list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;longitud []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;longitud (x#xs) = 1 + longitud xs&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
value &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 2. Demostrar que &lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 3. Definir la función&lt;br /&gt;
     fun intercambia :: &amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&lt;br /&gt;
  tal que (intercambia p) es el par obtenido intercambiando las&lt;br /&gt;
  componentes del par p. Por ejemplo,&lt;br /&gt;
     intercambia (u,v) = (v,u)&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun intercambia :: &amp;quot;&amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;intercambia (x,y) = (y,x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;intercambia (u,v) = (v,u)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹La definición de la función intercambia genera una regla de&lt;br /&gt;
  simplificación&lt;br /&gt;
  · intercambia.simps: intercambia (x,y) = (y,x)&lt;br /&gt;
  &lt;br /&gt;
  Se puede ver con &lt;br /&gt;
  · thm intercambia.simps &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm intercambia.simps&lt;br /&gt;
(* da intercambia (?x, ?y) = (?y, ?x) *)&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 4. (p.6) Demostrar que &lt;br /&gt;
     intercambia (intercambia (x,y)) = (x,y)&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by (simp only: intercambia.simps)&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  apply (simp only: intercambia.simps)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (x,y)&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración detallada *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  also have &amp;quot;… = (x,y)&amp;quot; &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;by (simp only: intercambia.simps)&amp;quot; para indicar que sólo se usa&lt;br /&gt;
    como regla de escritura la correspondiente a la definición de&lt;br /&gt;
    intercambia,&lt;br /&gt;
  · &amp;quot;also&amp;quot; para encadenar pasos ecuacionales,&lt;br /&gt;
  · &amp;quot;…&amp;quot; para representar la derecha de la igualdad anterior en un&lt;br /&gt;
    razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;finally&amp;quot; para indicar el último pasa de un razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.&lt;br /&gt;
  · &amp;quot;by simp&amp;quot; para indicar el método de demostración por simplificación y &lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas.›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 5. Definir, por recursión, la función&lt;br /&gt;
     inversa :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversa xs) es la lista obtenida invirtiendo el orden de los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     inversa [a,d,c] = [c,d,a]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun inversa :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversa []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;inversa (x#xs) = inversa xs @ [x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversa [a,d,c] = [c,d,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 6. (p. 9) Demostrar que &lt;br /&gt;
     inversa [x] = [x]&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹En la demostración anterior se usaron las siguientes reglas:&lt;br /&gt;
  · inversa.simps(1): inversa [] = []&lt;br /&gt;
  · inversa.simps(2): inversa (x#xs) = inversa xs @ [x]&lt;br /&gt;
  · append_Nil:       [] @ ys = ys&lt;br /&gt;
  Vamos a explicitar su aplicación.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
find_theorems&lt;br /&gt;
find_theorems &amp;quot;_ @ _ = _&amp;quot;&lt;br /&gt;
find_theorems &amp;quot;[] @ _ = _&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2)) (* inversa [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: inversa.simps(1)) (* [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: append_Nil)       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = (inversa []) @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot;  &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (inversa []) @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: inversa.simps(2))&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: inversa.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot; &lt;br /&gt;
    by (simp only: append_Nil) &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por inducción sobre los naturales ›&lt;br /&gt;
&lt;br /&gt;
text ‹[Principio de inducción sobre los naturales] Para demostrar una&lt;br /&gt;
  propiedad P para todos los números naturales basta probar que el 0&lt;br /&gt;
  tiene la propiedad P y que si n tiene la propiedad P, entonces n+1&lt;br /&gt;
  también la tiene.  &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre los naturales está&lt;br /&gt;
  formalizado en el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm nat.induct&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 7. Definir la función&lt;br /&gt;
     repite :: nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (repite n x) es la lista formada por n copias del elemento&lt;br /&gt;
  x. Por ejemplo, &lt;br /&gt;
     repite 3 a = [a,a,a]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;repite 0 x       = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) x = x # (repite n x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;repite 3 a = [a,a,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 8. (p. 18) Demostrar que &lt;br /&gt;
     longitud (repite n x) = n&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp      (* 1. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
  apply simp       (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa con simp_all es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp_all  (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (repite n x)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + n&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · A la derecha de proof se indica el método de la demostración.&lt;br /&gt;
  · (induct n) indica que la demostración se hará por inducción en n.&lt;br /&gt;
  · Se generan dos subobjetivos correspondientes a la base y el paso de&lt;br /&gt;
    inducción:&lt;br /&gt;
    1. longitud (repite 0 x) = 0&lt;br /&gt;
    2. ⋀n. longitud (repite n x) = n ⟹ &lt;br /&gt;
            longitud (repite (Suc n) x) = Suc n&lt;br /&gt;
    donde ⋀n se lee &amp;quot;para todo n&amp;quot;.  &lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente subobjetivo.&lt;br /&gt;
  · &amp;quot;fix n&amp;quot; indica &amp;quot;sea n un número natural cualquiera&amp;quot;&lt;br /&gt;
  · assume HI: &amp;quot;longitud (repite n x) = n&amp;quot; indica «supongamos que &lt;br /&gt;
    &amp;quot;longitud (repite n x) = n&amp;quot; y sea HI la etiqueta de este supuesto».&lt;br /&gt;
  · &amp;quot;using HI&amp;quot; usando la propiedad etiquetada con HI. ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot;&lt;br /&gt;
    by (simp only: repite.simps(1)&lt;br /&gt;
                   longitud.simps(1))&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by (simp only: repite.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (repite n x)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + n&amp;quot; &lt;br /&gt;
    by (simp only: HI)&lt;br /&gt;
  also have &amp;quot;… = Suc n&amp;quot;&lt;br /&gt;
    find_theorems &amp;quot;Suc _ = _ + _&amp;quot;&lt;br /&gt;
    by (simp only: Suc_eq_plus1_left)&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por inducción sobre listas ›&lt;br /&gt;
&lt;br /&gt;
text ‹Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
  que la lista vacía tiene la propiedad y que al añadir un elemento a&lt;br /&gt;
  una lista que tiene la propiedad se obtiene otra lista que también&lt;br /&gt;
  tiene la propiedad. &lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
  mediante el teorema list.induct &lt;br /&gt;
     ⟦P []; &lt;br /&gt;
      ⋀x xs. P xs ⟹ P (x#xs)⟧ &lt;br /&gt;
     ⟹ P xs&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm list.induct&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 9. Definir la función&lt;br /&gt;
     conc :: &amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (conc xs ys) es la concatención de las listas xs e ys. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun conc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;conc []     ys = ys&amp;quot;&lt;br /&gt;
| &amp;quot;conc (x#xs) ys = x # (conc xs ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 10. (p. 24) Demostrar que &lt;br /&gt;
     conc xs (conc ys zs) = (conc xs ys) zs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  apply (induct xs) (*  1. conc [] (conc ys zs) = conc (conc [] ys) zs&lt;br /&gt;
                        2. ⋀a xs.&lt;br /&gt;
                              conc xs (conc ys zs) =&lt;br /&gt;
                              conc (conc xs ys) zs ⟹&lt;br /&gt;
                              conc (a # xs) (conc ys zs) =&lt;br /&gt;
                              conc (conc (a # xs) ys) zs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x # (conc (conc xs ys) zs)&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = x # (conc (conc xs ys) zs)&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 11. Refutar que &lt;br /&gt;
     conc xs ys = conc ys xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;conc xs ys = conc ys xs&amp;quot;&lt;br /&gt;
  quickcheck&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text ‹ Encuentra el contraejemplo, &lt;br /&gt;
  xs = [a2]&lt;br /&gt;
  ys = [a1] ›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 12. (p. 28) Demostrar que &lt;br /&gt;
     conc xs [] = xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. conc [] [] = []&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             conc xs [] = xs ⟹&lt;br /&gt;
                             conc (a # xs) [] = a # xs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x # xs&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* declare [[show_types]] *)&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x # xs&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1))&lt;br /&gt;
next &lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = x # xs&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 13. (p. 30) Demostrar que &lt;br /&gt;
     longitud (conc xs ys) = longitud xs + longitud ys&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. longitud (conc [] ys) =&lt;br /&gt;
                          longitud [] + longitud ys&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             longitud (conc xs ys) =&lt;br /&gt;
                             longitud xs + longitud ys ⟹&lt;br /&gt;
                             longitud (conc (a # xs) ys) =&lt;br /&gt;
                             longitud (a # xs) + longitud ys *) &lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (conc xs ys)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs + longitud ys&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1)&lt;br /&gt;
                   longitud.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (conc xs ys)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs + longitud ys&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Inducción correspondiente a la definición recursiva ›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 14. Definir la función&lt;br /&gt;
     coge :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (coge n xs) es la lista de los n primeros elementos de xs. Por &lt;br /&gt;
  ejemplo, &lt;br /&gt;
     coge 2 [a,c,d,b,e] = [a,c]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun coge :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;coge n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge 0 xs           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge (Suc n) (x#xs) = x # (coge n xs)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;coge 2 [a,c,d,b,e] = [a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 15. Definir la función&lt;br /&gt;
     elimina :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (elimina n xs) es la lista obtenida eliminando los n primeros&lt;br /&gt;
  elementos de xs. Por ejemplo, &lt;br /&gt;
     elimina 2 [a,c,d,b,e] = [d,b,e]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun elimina :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;elimina n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;elimina 0 xs           = xs&amp;quot;&lt;br /&gt;
| &amp;quot;elimina (Suc n) (x#xs) = elimina n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;elimina 2 [a,c,d,b,e] = [d,b,e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ &lt;br /&gt;
  La definición coge genera el esquema de inducción coge.induct:&lt;br /&gt;
     ⟦⋀n. P n []; &lt;br /&gt;
      ⋀x xs. P 0 (x#xs); &lt;br /&gt;
      ⋀n x xs. P n xs ⟹ P (Suc n) (x#xs)⟧&lt;br /&gt;
     ⟹ P n x&lt;br /&gt;
&lt;br /&gt;
  Puede verse usando &amp;quot;thm coge.induct&amp;quot;. ›&lt;br /&gt;
&lt;br /&gt;
thm coge.induct&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 16. (p. 35) Demostrar que &lt;br /&gt;
     conc (coge n xs) (elimina n xs) = xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  apply (induct rule: coge.induct) &lt;br /&gt;
      (*  1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
          2. ⋀v va. conc (coge 0 (v # va)) (elimina 0 (v # va)) =&lt;br /&gt;
                     v # va&lt;br /&gt;
          3. ⋀n x xs. conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
                       conc (coge (Suc n) (x # xs)) &lt;br /&gt;
                            (elimina (Suc n) (x # xs)) =&lt;br /&gt;
                       x # xs *)&lt;br /&gt;
    apply simp_all&lt;br /&gt;
      (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  by (induct rule: coge.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n and x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x#(conc (coge n xs) (elimina n xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x#xs&amp;quot; &lt;br /&gt;
    using HI by simp  &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentario sobre la demostración anterior:&lt;br /&gt;
  · (induct rule: coge.induct) indica que el método de demostración es&lt;br /&gt;
    por el esquema de inducción correspondiente a la definición de la&lt;br /&gt;
    función coge.&lt;br /&gt;
  · Se generan 3 subobjetivos:&lt;br /&gt;
    · 1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
    · 2. ⋀x xs. conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&lt;br /&gt;
    · 3. ⋀n x xs. &lt;br /&gt;
            conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
            conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = x#xs&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; &lt;br /&gt;
    by (simp only: coge.simps(1)&lt;br /&gt;
                   elimina.simps(1)&lt;br /&gt;
                   conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; &lt;br /&gt;
    by (simp only: coge.simps(2)&lt;br /&gt;
                   elimina.simps(2)&lt;br /&gt;
                   conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix n and x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; &lt;br /&gt;
    by (simp only: coge.simps(3)&lt;br /&gt;
                   elimina.simps(3))&lt;br /&gt;
  also have &amp;quot;… = x#(conc (coge n xs) (elimina n xs))&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = x#xs&amp;quot; &lt;br /&gt;
    using HI by (simp only:) &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por casos ›&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 17. Definir la función&lt;br /&gt;
     esVacia :: &amp;#039;a list ⇒ bool&lt;br /&gt;
  tal que (esVacia xs) se verifica si xs es la lista vacía. Por ejemplo,&lt;br /&gt;
     esVacia []  = True&lt;br /&gt;
     esVacia [1] = False&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun esVacia :: &amp;quot;&amp;#039;a list ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;esVacia []     = True&amp;quot;&lt;br /&gt;
| &amp;quot;esVacia (x#xs) = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;esVacia []  = True&amp;quot;&lt;br /&gt;
value &amp;quot;esVacia [a] = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 18 (p. 39) . Demostrar que &lt;br /&gt;
     esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                    esVacia xs = esVacia (conc xs xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; es el método de demostración por casos según xs.&lt;br /&gt;
  · Se generan dos subobjetivos  correspondientes a los dos&lt;br /&gt;
    constructores de listas:&lt;br /&gt;
    · 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
    · 2. ⋀y ys. xs = y#ys ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica &amp;quot;usando la propiedad anterior&amp;quot;&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by (simp only: esVacia.simps(2)&lt;br /&gt;
                   conc.simps(2))&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &amp;quot;assume xs = []&amp;quot;&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &amp;quot;fix y ys assume xs = y#ys&amp;quot;›&lt;br /&gt;
&lt;br /&gt;
(* La demostración con el patrón sugerido es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case (Cons x xs)&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Heurística de generalización ›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 19. Definir la función&lt;br /&gt;
     inversaAc :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversaAc xs) es a inversa de xs calculada usando&lt;br /&gt;
  acumuladores. Por ejemplo, &lt;br /&gt;
     inversaAc [a,c,b,e] = [e,b,c,a]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun inversaAcAux :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAcAux [] ys     = ys&amp;quot;&lt;br /&gt;
| &amp;quot;inversaAcAux (x#xs) ys = inversaAcAux xs (x#ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition inversaAc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAc xs = inversaAcAux xs []&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversaAc [a,c,b,e] = [e,b,c,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Lema. [Ejemplo de equivalencia entre las definiciones]&lt;br /&gt;
  La inversa de [a,b,c] es lo mismo calculada con la primera definición&lt;br /&gt;
  que con la segunda.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc [a,b,c] = inversa [a,b,c]&amp;quot;&lt;br /&gt;
  by (simp add: inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Ejemplo fallido de demostración por inducción]&lt;br /&gt;
  El siguiente intento de demostrar que para cualquier lista xs, se&lt;br /&gt;
  tiene que  &amp;quot;inversaAc xs = inversa xs&amp;quot; falla.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;inversaAc [] = inversa []&amp;quot; &lt;br /&gt;
    by (simp add: inversaAc_def)&lt;br /&gt;
next&lt;br /&gt;
  fix a :: &amp;quot;&amp;#039;b&amp;quot; and xs :: &amp;quot;&amp;#039;b list&amp;quot; &lt;br /&gt;
  assume HI: &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  have &amp;quot;inversaAc (a#xs) = inversaAcAux (a#xs) []&amp;quot; &lt;br /&gt;
    by (simp add: inversaAc_def)&lt;br /&gt;
  also have &amp;quot;… = inversaAcAux xs [a]&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = inversa (a#xs)&amp;quot;&lt;br /&gt;
  (* Problema: la hipótesis de inducción no es aplicable. *)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Heurística de generalización]&lt;br /&gt;
  Cuando se use demostración estructural, cuantificar universalmente las &lt;br /&gt;
  variables libres (o, equivalentemente, considerar las variables libres&lt;br /&gt;
  como variables arbitrarias).&lt;br /&gt;
&lt;br /&gt;
  Lema. [Lema con generalización]&lt;br /&gt;
  Para toda lista ys se tiene &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 20. (p. 44) Demostrar que &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  apply (induct xs arbitrary: ys) &lt;br /&gt;
     (* 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
        2. ⋀a xs ys.&lt;br /&gt;
              (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
              inversaAcAux (a # xs) ys = inversa (a # xs) @ ys *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  by (induct xs arbitrary: ys) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux [] ys = (inversa [])@ys&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a :: &amp;quot;&amp;#039;b&amp;quot; and xs :: &amp;quot;&amp;#039;b list&amp;quot; &lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; &lt;br /&gt;
      using HI by simp&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; using [[simp_trace]] &lt;br /&gt;
      by simp &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(induct xs arbitrary: ys)&amp;quot; es el método de demostración por&lt;br /&gt;
    inducción sobre xs usando ys como variable arbitraria.&lt;br /&gt;
  · Se generan dos subobjetivos:&lt;br /&gt;
    · 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
    · 2. ⋀a xs ys. (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
                    inversaAcAux (a # xs) ys = inversa (a # xs) @ ys&lt;br /&gt;
  · Dentro de una demostración se pueden incluir otras demostraciones.&lt;br /&gt;
  · Para demostrar la propiedad universal &amp;quot;⋀ys. P(ys)&amp;quot; se elige una&lt;br /&gt;
    lista arbitraria (con &amp;quot;fix ys&amp;quot;) y se demuestra &amp;quot;P(ys)&amp;quot;. ›&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. En el paso &amp;quot;inversa xs@(a#ys) = inversa (a#xs)@ys&amp;quot; se usan&lt;br /&gt;
  lemas de la teoría List. Se puede observar, insertano &lt;br /&gt;
     using [[simp_trace]]&lt;br /&gt;
  entre la igualdad y by simp, que los lemas usados son &lt;br /&gt;
  · List.append_simps_1: []@ys = ys&lt;br /&gt;
  · List.append_simps_2: (x#xs)@ys = x#(xs@ys)&lt;br /&gt;
  · List.append_assoc:   (xs @ ys) @ zs = xs @ (ys @ zs)&lt;br /&gt;
  Las dos primeras son las ecuaciones de la definición de append.&lt;br /&gt;
&lt;br /&gt;
  En la siguiente demostración se detallan los lemas utilizados.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2))&lt;br /&gt;
    (* inversa xs @ (a # ys) = (inversa xs @ [a]) @ ys*)&lt;br /&gt;
  apply (simp only: append_assoc)&lt;br /&gt;
    (* inversa xs @ (a # ys) = inversa xs @ ([a] @ ys) *)&lt;br /&gt;
  apply (simp only: append.simps(2))&lt;br /&gt;
    (* inversa xs @ (a # ys) = inversa xs @ (a # ([] @ ys)) *)&lt;br /&gt;
  apply (simp only: append.simps(1))&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa detallada del lema auxiliar›&lt;br /&gt;
lemma auxiliar: &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(inversa xs)@(a#ys) = (inversa xs)@(a#([]@ys))&amp;quot; &lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (inversa xs)@([a]@ys)&amp;quot; &lt;br /&gt;
    by (simp only: append.simps(2))&lt;br /&gt;
  also have &amp;quot;… = ((inversa xs)@[a])@ys&amp;quot; &lt;br /&gt;
    by (simp only: append_assoc)&lt;br /&gt;
  also have &amp;quot;… = (inversa (a#xs))@ys&amp;quot; &lt;br /&gt;
    by (simp only: inversa.simps(2))&lt;br /&gt;
  finally show ?thesis &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma inversaAcAux_es_inversa:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  fix ys :: &amp;quot;&amp;#039;b list&amp;quot;&lt;br /&gt;
  show &amp;quot;inversaAcAux [] ys = (inversa [])@ys&amp;quot; &lt;br /&gt;
    by (simp only: inversaAcAux.simps(1)&lt;br /&gt;
                   inversa.simps(1)&lt;br /&gt;
                   append.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix a :: &amp;quot;&amp;#039;b&amp;quot; and xs :: &amp;quot;&amp;#039;b list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; &lt;br /&gt;
      by (simp only: inversaAcAux.simps(2))&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; &lt;br /&gt;
      using HI by (simp only:)&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; &lt;br /&gt;
      by (rule auxiliar) &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 21. (p. 43) Demostrar que &lt;br /&gt;
     inversaAc xs = inversa xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  apply (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  by (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text ‹Comentario de la demostración anterior:&lt;br /&gt;
  · &amp;quot;(simp add: inversaAcAux_es_inversa inversaAc_def)&amp;quot; es el método de &lt;br /&gt;
    demostración por simplificación usando como regla de simplificación &lt;br /&gt;
    las propiedades inversaAcAux_es_inversa e inversaAc_def. ›&lt;br /&gt;
 &lt;br /&gt;
section ‹Demostración por inducción para funciones de orden superior ›&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 22. Definir la función&lt;br /&gt;
     sum :: nat list ⇒ nat&lt;br /&gt;
  tal que (sum xs) es la suma de los elementos de xs. Por ejemplo,&lt;br /&gt;
     sum [3,2,5] = 10&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun sum :: &amp;quot;nat list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sum []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;sum (x#xs) = x + sum xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sum [3,2,5] = 10&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 23. Definir la función&lt;br /&gt;
     map :: (&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&lt;br /&gt;
  tal que (map f xs) es la lista obtenida aplicando la función f a los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     map (λx. 2*x) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map ((*) 2) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map ((+) 2)   [3::nat,2,5] = [5,4,7]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun map :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&amp;quot; where&lt;br /&gt;
  &amp;quot;map f []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;map f (x#xs) = (f x) # map f xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;map (λx. 2*x) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map ((*) 2)   [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map ((+) 2)   [3::nat,2,5] = [5,4,7]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 24. (p. 45) Demostrar que &lt;br /&gt;
     sum (map ((*) 2) xs) = 2 * (sum xs)&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. sum (map (( * ) 2) []) = 2 * sum []&lt;br /&gt;
        2. ⋀a xs. sum (map (( * ) 2) xs) = 2 * sum xs ⟹&lt;br /&gt;
                  sum (map (( * ) 2) (a # xs)) = 2 * sum (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map ((*) 2) []) = 2 * (sum [])&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map ((*) 2) (a#xs)) = sum ((2*a)#(map ((*) 2) xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 2*a + sum (map ((*) 2) xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 2*a + 2*(sum xs)&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = 2*(a + sum xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;sum (map ((*) 2) (a#xs)) = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map ((*) 2) []) = 2 * (sum [])&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(1)&lt;br /&gt;
                   sum.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map ((*) 2) (a#xs)) = sum ((2*a)#(map ((*) 2) xs))&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 2*a + sum (map ((*) 2) xs)&amp;quot; &lt;br /&gt;
    by (simp only: sum.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 2*a + 2*(sum xs)&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = 2*(a + sum xs)&amp;quot; &lt;br /&gt;
    find_theorems &amp;quot;_ * (_ + _)&amp;quot;&lt;br /&gt;
    by (simp only: add_mult_distrib2)&lt;br /&gt;
  also have &amp;quot;… = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by (simp only: sum.simps(2))&lt;br /&gt;
  finally show &amp;quot;sum (map ((*) 2) (a#xs)) = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 25. (p. 48) Demostrar que &lt;br /&gt;
     longitud (map f xs) = longitud xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. longitud (map f []) = longitud []&lt;br /&gt;
        2. ⋀a xs. longitud (map f xs) = longitud xs ⟹&lt;br /&gt;
                   longitud (map f (a # xs)) = longitud (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (map f xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(1)&lt;br /&gt;
                   longitud.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (map f xs)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Referencias›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  · J.A. Alonso. &amp;quot;Razonamiento sobre programas&amp;quot; http://goo.gl/R06O3&lt;br /&gt;
  · G. Hutton. &amp;quot;Programming in Haskell&amp;quot;. Cap. 13 &amp;quot;Reasoning about&lt;br /&gt;
    programms&amp;quot;. &lt;br /&gt;
  · S. Thompson. &amp;quot;Haskell: the Craft of Functional Programming, 3rd&lt;br /&gt;
    Edition. Cap. 8 &amp;quot;Reasoning about programms&amp;quot;. &lt;br /&gt;
  · L. Paulson. &amp;quot;ML for the Working Programmer, 2nd Edition&amp;quot;. Cap. 6. &lt;br /&gt;
    &amp;quot;Reasoning about functional programs&amp;quot;. &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=818</id>
		<title>Razonamiento sobre programas en Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=818"/>
		<updated>2020-04-16T05:17:29Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 6: Razonamiento sobre programas›&lt;br /&gt;
&lt;br /&gt;
theory T6_Razonamiento_sobre_programas&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se demuestra con Isabelle las propiedades de los&lt;br /&gt;
  programas funcionales de tema 6 http://bit.ly/2Za6YWY&lt;br /&gt;
&lt;br /&gt;
  Para cada propiedades se presentan distintos tipos de demostraciones:&lt;br /&gt;
  automáticas, aplicativas y declarativas.› &lt;br /&gt;
&lt;br /&gt;
(* declare [[names_short]] *)&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento ecuacional›&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejemplo 1. Definir, por recursión, la función&lt;br /&gt;
     longitud :: &amp;#039;a list ⇒ nat&lt;br /&gt;
  tal que (longitud xs) es la longitud de la listas xs. Por ejemplo,&lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
fun longitud :: &amp;quot;&amp;#039;a list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;longitud []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;longitud (x#xs) = 1 + longitud xs&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
value &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 2. Demostrar que &lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 3. Definir la función&lt;br /&gt;
     fun intercambia :: &amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&lt;br /&gt;
  tal que (intercambia p) es el par obtenido intercambiando las&lt;br /&gt;
  componentes del par p. Por ejemplo,&lt;br /&gt;
     intercambia (u,v) = (v,u)&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun intercambia :: &amp;quot;&amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;intercambia (x,y) = (y,x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;intercambia (u,v) = (v,u)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹La definición de la función intercambia genera una regla de&lt;br /&gt;
  simplificación&lt;br /&gt;
  · intercambia.simps: intercambia (x,y) = (y,x)&lt;br /&gt;
  &lt;br /&gt;
  Se puede ver con &lt;br /&gt;
  · thm intercambia.simps &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm intercambia.simps&lt;br /&gt;
(* da intercambia (?x, ?y) = (?y, ?x) *)&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 4. (p.6) Demostrar que &lt;br /&gt;
     intercambia (intercambia (x,y)) = (x,y)&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by (simp only: intercambia.simps)&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  apply (simp only: intercambia.simps)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (x,y)&amp;quot; &lt;br /&gt;
    by simp &lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración detallada *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  also have &amp;quot;… = (x,y)&amp;quot; &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;by (simp only: intercambia.simps)&amp;quot; para indicar que sólo se usa&lt;br /&gt;
    como regla de escritura la correspondiente a la definición de&lt;br /&gt;
    intercambia,&lt;br /&gt;
  · &amp;quot;also&amp;quot; para encadenar pasos ecuacionales,&lt;br /&gt;
  · &amp;quot;…&amp;quot; para representar la derecha de la igualdad anterior en un&lt;br /&gt;
    razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;finally&amp;quot; para indicar el último pasa de un razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.&lt;br /&gt;
  · &amp;quot;by simp&amp;quot; para indicar el método de demostración por simplificación y &lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas.›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 5. Definir, por recursión, la función&lt;br /&gt;
     inversa :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversa xs) es la lista obtenida invirtiendo el orden de los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     inversa [a,d,c] = [c,d,a]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun inversa :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversa []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;inversa (x#xs) = inversa xs @ [x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversa [a,d,c] = [c,d,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 6. (p. 9) Demostrar que &lt;br /&gt;
     inversa [x] = [x]&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹En la demostración anterior se usaron las siguientes reglas:&lt;br /&gt;
  · inversa.simps(1): inversa [] = []&lt;br /&gt;
  · inversa.simps(2): inversa (x#xs) = inversa xs @ [x]&lt;br /&gt;
  · append_Nil:       [] @ ys = ys&lt;br /&gt;
  Vamos a explicitar su aplicación.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
find_theorems&lt;br /&gt;
find_theorems &amp;quot;_ @ _ = _&amp;quot;&lt;br /&gt;
find_theorems &amp;quot;[] @ _ = _&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2)) (* inversa [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: inversa.simps(1)) (* [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: append_Nil)       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = (inversa []) @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot;  &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (inversa []) @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: inversa.simps(2))&lt;br /&gt;
  also have &amp;quot;… = [] @ [x]&amp;quot; &lt;br /&gt;
    by (simp only: inversa.simps(1))&lt;br /&gt;
  also have &amp;quot;… = [x]&amp;quot; &lt;br /&gt;
    by (simp only: append_Nil) &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por inducción sobre los naturales ›&lt;br /&gt;
&lt;br /&gt;
text ‹[Principio de inducción sobre los naturales] Para demostrar una&lt;br /&gt;
  propiedad P para todos los números naturales basta probar que el 0&lt;br /&gt;
  tiene la propiedad P y que si n tiene la propiedad P, entonces n+1&lt;br /&gt;
  también la tiene.  &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre los naturales está&lt;br /&gt;
  formalizado en el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm nat.induct&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 7. Definir la función&lt;br /&gt;
     repite :: nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (repite n x) es la lista formada por n copias del elemento&lt;br /&gt;
  x. Por ejemplo, &lt;br /&gt;
     repite 3 a = [a,a,a]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;repite 0 x       = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) x = x # (repite n x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;repite 3 a = [a,a,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 8. (p. 18) Demostrar que &lt;br /&gt;
     longitud (repite n x) = n&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp      (* 1. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
  apply simp       (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa con simp_all es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp_all  (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (repite n x)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + n&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · A la derecha de proof se indica el método de la demostración.&lt;br /&gt;
  · (induct n) indica que la demostración se hará por inducción en n.&lt;br /&gt;
  · Se generan dos subobjetivos correspondientes a la base y el paso de&lt;br /&gt;
    inducción:&lt;br /&gt;
    1. longitud (repite 0 x) = 0&lt;br /&gt;
    2. ⋀n. longitud (repite n x) = n ⟹ &lt;br /&gt;
            longitud (repite (Suc n) x) = Suc n&lt;br /&gt;
    donde ⋀n se lee &amp;quot;para todo n&amp;quot;.  &lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente subobjetivo.&lt;br /&gt;
  · &amp;quot;fix n&amp;quot; indica &amp;quot;sea n un número natural cualquiera&amp;quot;&lt;br /&gt;
  · assume HI: &amp;quot;longitud (repite n x) = n&amp;quot; indica «supongamos que &lt;br /&gt;
    &amp;quot;longitud (repite n x) = n&amp;quot; y sea HI la etiqueta de este supuesto».&lt;br /&gt;
  · &amp;quot;using HI&amp;quot; usando la propiedad etiquetada con HI. ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot;&lt;br /&gt;
    by (simp only: repite.simps(1)&lt;br /&gt;
                   longitud.simps(1))&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by (simp only: repite.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (repite n x)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + n&amp;quot; &lt;br /&gt;
    by (simp only: HI)&lt;br /&gt;
  also have &amp;quot;… = Suc n&amp;quot;&lt;br /&gt;
    find_theorems &amp;quot;Suc _ = _ + _&amp;quot;&lt;br /&gt;
    by (simp only: Suc_eq_plus1_left)&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por inducción sobre listas ›&lt;br /&gt;
&lt;br /&gt;
text ‹Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
  que la lista vacía tiene la propiedad y que al añadir un elemento a&lt;br /&gt;
  una lista que tiene la propiedad se obtiene otra lista que también&lt;br /&gt;
  tiene la propiedad. &lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
  mediante el teorema list.induct &lt;br /&gt;
     ⟦P []; &lt;br /&gt;
      ⋀x xs. P xs ⟹ P (x#xs)⟧ &lt;br /&gt;
     ⟹ P xs&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
thm list.induct&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 9. Definir la función&lt;br /&gt;
     conc :: &amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (conc xs ys) es la concatención de las listas xs e ys. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun conc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;conc []     ys = ys&amp;quot;&lt;br /&gt;
| &amp;quot;conc (x#xs) ys = x # (conc xs ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 10. (p. 24) Demostrar que &lt;br /&gt;
     conc xs (conc ys zs) = (conc xs ys) zs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  apply (induct xs) (*  1. conc [] (conc ys zs) = conc (conc [] ys) zs&lt;br /&gt;
                        2. ⋀a xs.&lt;br /&gt;
                              conc xs (conc ys zs) =&lt;br /&gt;
                              conc (conc xs ys) zs ⟹&lt;br /&gt;
                              conc (a # xs) (conc ys zs) =&lt;br /&gt;
                              conc (conc (a # xs) ys) zs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x # (conc (conc xs ys) zs)&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = x # (conc (conc xs ys) zs)&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 11. Refutar que &lt;br /&gt;
     conc xs ys = conc ys xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;conc xs ys = conc ys xs&amp;quot;&lt;br /&gt;
  quickcheck&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text ‹ Encuentra el contraejemplo, &lt;br /&gt;
  xs = [a2]&lt;br /&gt;
  ys = [a1] ›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 12. (p. 28) Demostrar que &lt;br /&gt;
     conc xs [] = xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. conc [] [] = []&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             conc xs [] = xs ⟹&lt;br /&gt;
                             conc (a # xs) [] = a # xs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x # xs&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* declare [[show_types]] *)&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x # xs&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1))&lt;br /&gt;
next &lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = x # xs&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 13. (p. 30) Demostrar que &lt;br /&gt;
     longitud (conc xs ys) = longitud xs + longitud ys&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. longitud (conc [] ys) =&lt;br /&gt;
                          longitud [] + longitud ys&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             longitud (conc xs ys) =&lt;br /&gt;
                             longitud xs + longitud ys ⟹&lt;br /&gt;
                             longitud (conc (a # xs) ys) =&lt;br /&gt;
                             longitud (a # xs) + longitud ys *) &lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (conc xs ys)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs + longitud ys&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1)&lt;br /&gt;
                   longitud.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (conc xs ys)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs + longitud ys&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Inducción correspondiente a la definición recursiva ›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 14. Definir la función&lt;br /&gt;
     coge :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (coge n xs) es la lista de los n primeros elementos de xs. Por &lt;br /&gt;
  ejemplo, &lt;br /&gt;
     coge 2 [a,c,d,b,e] = [a,c]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun coge :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;coge n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge 0 xs           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge (Suc n) (x#xs) = x # (coge n xs)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;coge 2 [a,c,d,b,e] = [a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 15. Definir la función&lt;br /&gt;
     elimina :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (elimina n xs) es la lista obtenida eliminando los n primeros&lt;br /&gt;
  elementos de xs. Por ejemplo, &lt;br /&gt;
     elimina 2 [a,c,d,b,e] = [d,b,e]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun elimina :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;elimina n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;elimina 0 xs           = xs&amp;quot;&lt;br /&gt;
| &amp;quot;elimina (Suc n) (x#xs) = elimina n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;elimina 2 [a,c,d,b,e] = [d,b,e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹ &lt;br /&gt;
  La definición coge genera el esquema de inducción coge.induct:&lt;br /&gt;
     ⟦⋀n. P n []; &lt;br /&gt;
      ⋀x xs. P 0 (x#xs); &lt;br /&gt;
      ⋀n x xs. P n xs ⟹ P (Suc n) (x#xs)⟧&lt;br /&gt;
     ⟹ P n x&lt;br /&gt;
&lt;br /&gt;
  Puede verse usando &amp;quot;thm coge.induct&amp;quot;. ›&lt;br /&gt;
&lt;br /&gt;
thm coge.induct&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 16. (p. 35) Demostrar que &lt;br /&gt;
     conc (coge n xs) (elimina n xs) = xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  apply (induct rule: coge.induct) &lt;br /&gt;
      (*  1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
          2. ⋀v va. conc (coge 0 (v # va)) (elimina 0 (v # va)) =&lt;br /&gt;
                     v # va&lt;br /&gt;
          3. ⋀n x xs. conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
                       conc (coge (Suc n) (x # xs)) &lt;br /&gt;
                            (elimina (Suc n) (x # xs)) =&lt;br /&gt;
                       x # xs *)&lt;br /&gt;
    apply simp_all&lt;br /&gt;
      (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  by (induct rule: coge.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n and x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x#(conc (coge n xs) (elimina n xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = x#xs&amp;quot; &lt;br /&gt;
    using HI by simp  &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentario sobre la demostración anterior:&lt;br /&gt;
  · (induct rule: coge.induct) indica que el método de demostración es&lt;br /&gt;
    por el esquema de inducción correspondiente a la definición de la&lt;br /&gt;
    función coge.&lt;br /&gt;
  · Se generan 3 subobjetivos:&lt;br /&gt;
    · 1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
    · 2. ⋀x xs. conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&lt;br /&gt;
    · 3. ⋀n x xs. &lt;br /&gt;
            conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
            conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = x#xs&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; &lt;br /&gt;
    by (simp only: coge.simps(1)&lt;br /&gt;
                   elimina.simps(1)&lt;br /&gt;
                   conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; &lt;br /&gt;
    by (simp only: coge.simps(2)&lt;br /&gt;
                   elimina.simps(2)&lt;br /&gt;
                   conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix n and x :: &amp;quot;&amp;#039;a&amp;quot; and xs :: &amp;quot;&amp;#039;a list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; &lt;br /&gt;
    by (simp only: coge.simps(3)&lt;br /&gt;
                   elimina.simps(3))&lt;br /&gt;
  also have &amp;quot;… = x#(conc (coge n xs) (elimina n xs))&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(2))&lt;br /&gt;
  also have &amp;quot;… = x#xs&amp;quot; &lt;br /&gt;
    using HI by (simp only:) &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Razonamiento por casos ›&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 17. Definir la función&lt;br /&gt;
     esVacia :: &amp;#039;a list ⇒ bool&lt;br /&gt;
  tal que (esVacia xs) se verifica si xs es la lista vacía. Por ejemplo,&lt;br /&gt;
     esVacia []  = True&lt;br /&gt;
     esVacia [1] = False&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun esVacia :: &amp;quot;&amp;#039;a list ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;esVacia []     = True&amp;quot;&lt;br /&gt;
| &amp;quot;esVacia (x#xs) = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;esVacia []  = True&amp;quot;&lt;br /&gt;
value &amp;quot;esVacia [a] = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 18 (p. 39) . Demostrar que &lt;br /&gt;
     esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                    esVacia xs = esVacia (conc xs xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; es el método de demostración por casos según xs.&lt;br /&gt;
  · Se generan dos subobjetivos  correspondientes a los dos&lt;br /&gt;
    constructores de listas:&lt;br /&gt;
    · 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
    · 2. ⋀y ys. xs = y#ys ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica &amp;quot;usando la propiedad anterior&amp;quot;&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by (simp only: conc.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by (simp only: esVacia.simps(2)&lt;br /&gt;
                   conc.simps(2))&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &amp;quot;assume xs = []&amp;quot;&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &amp;quot;fix y ys assume xs = y#ys&amp;quot;›&lt;br /&gt;
&lt;br /&gt;
(* La demostración con el patrón sugerido es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case (Cons x xs)&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Heurística de generalización ›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 19. Definir la función&lt;br /&gt;
     inversaAc :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversaAc xs) es a inversa de xs calculada usando&lt;br /&gt;
  acumuladores. Por ejemplo, &lt;br /&gt;
     inversaAc [a,c,b,e] = [e,b,c,a]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun inversaAcAux :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAcAux [] ys     = ys&amp;quot;&lt;br /&gt;
| &amp;quot;inversaAcAux (x#xs) ys = inversaAcAux xs (x#ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition inversaAc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAc xs = inversaAcAux xs []&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversaAc [a,c,b,e] = [e,b,c,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Lema. [Ejemplo de equivalencia entre las definiciones]&lt;br /&gt;
  La inversa de [a,b,c] es lo mismo calculada con la primera definición&lt;br /&gt;
  que con la segunda.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc [a,b,c] = inversa [a,b,c]&amp;quot;&lt;br /&gt;
  by (simp add: inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Ejemplo fallido de demostración por inducción]&lt;br /&gt;
  El siguiente intento de demostrar que para cualquier lista xs, se&lt;br /&gt;
  tiene que  &amp;quot;inversaAc xs = inversa xs&amp;quot; falla.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;inversaAc [] = inversa []&amp;quot; &lt;br /&gt;
    by (simp add: inversaAc_def)&lt;br /&gt;
next&lt;br /&gt;
  fix a :: &amp;quot;&amp;#039;b&amp;quot; and xs :: &amp;quot;&amp;#039;b list&amp;quot; &lt;br /&gt;
  assume HI: &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  have &amp;quot;inversaAc (a#xs) = inversaAcAux (a#xs) []&amp;quot; &lt;br /&gt;
    by (simp add: inversaAc_def)&lt;br /&gt;
  also have &amp;quot;… = inversaAcAux xs [a]&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = inversa (a#xs)&amp;quot;&lt;br /&gt;
  (* Problema: la hipótesis de inducción no es aplicable. *)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. [Heurística de generalización]&lt;br /&gt;
  Cuando se use demostración estructural, cuantificar universalmente las &lt;br /&gt;
  variables libres (o, equivalentemente, considerar las variables libres&lt;br /&gt;
  como variables arbitrarias).&lt;br /&gt;
&lt;br /&gt;
  Lema. [Lema con generalización]&lt;br /&gt;
  Para toda lista ys se tiene &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 20. (p. 44) Demostrar que &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  apply (induct xs arbitrary: ys) &lt;br /&gt;
     (* 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
        2. ⋀a xs ys.&lt;br /&gt;
              (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
              inversaAcAux (a # xs) ys = inversa (a # xs) @ ys *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  by (induct xs arbitrary: ys) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux [] ys = (inversa [])@ys&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a :: &amp;quot;&amp;#039;b&amp;quot; and xs :: &amp;quot;&amp;#039;b list&amp;quot; &lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; &lt;br /&gt;
      using HI by simp&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; using [[simp_trace]] &lt;br /&gt;
      by simp &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(induct xs arbitrary: ys)&amp;quot; es el método de demostración por&lt;br /&gt;
    inducción sobre xs usando ys como variable arbitraria.&lt;br /&gt;
  · Se generan dos subobjetivos:&lt;br /&gt;
    · 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
    · 2. ⋀a xs ys. (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
                    inversaAcAux (a # xs) ys = inversa (a # xs) @ ys&lt;br /&gt;
  · Dentro de una demostración se pueden incluir otras demostraciones.&lt;br /&gt;
  · Para demostrar la propiedad universal &amp;quot;⋀ys. P(ys)&amp;quot; se elige una&lt;br /&gt;
    lista arbitraria (con &amp;quot;fix ys&amp;quot;) y se demuestra &amp;quot;P(ys)&amp;quot;. ›&lt;br /&gt;
&lt;br /&gt;
text ‹Nota. En el paso &amp;quot;inversa xs@(a#ys) = inversa (a#xs)@ys&amp;quot; se usan&lt;br /&gt;
  lemas de la teoría List. Se puede observar, insertano &lt;br /&gt;
     using [[simp_trace]]&lt;br /&gt;
  entre la igualdad y by simp, que los lemas usados son &lt;br /&gt;
  · List.append_simps_1: []@ys = ys&lt;br /&gt;
  · List.append_simps_2: (x#xs)@ys = x#(xs@ys)&lt;br /&gt;
  · List.append_assoc:   (xs @ ys) @ zs = xs @ (ys @ zs)&lt;br /&gt;
  Las dos primeras son las ecuaciones de la definición de append.&lt;br /&gt;
&lt;br /&gt;
  En la siguiente demostración se detallan los lemas utilizados.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2))&lt;br /&gt;
    (* inversa xs @ (a # ys) = (inversa xs @ [a]) @ ys*)&lt;br /&gt;
  apply (simp only: append_assoc)&lt;br /&gt;
    (* inversa xs @ (a # ys) = inversa xs @ ([a] @ ys) *)&lt;br /&gt;
  apply (simp only: append.simps(2))&lt;br /&gt;
    (* inversa xs @ (a # ys) = inversa xs @ (a # ([] @ ys)) *)&lt;br /&gt;
  apply (simp only: append.simps(1))&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa detallada del lema auxiliar›&lt;br /&gt;
lemma auxiliar: &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(inversa xs)@(a#ys) = (inversa xs)@(a#([]@ys))&amp;quot; &lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (inversa xs)@([a]@ys)&amp;quot; &lt;br /&gt;
    by (simp only: append.simps(2))&lt;br /&gt;
  also have &amp;quot;… = ((inversa xs)@[a])@ys&amp;quot; &lt;br /&gt;
    by (simp only: append_assoc)&lt;br /&gt;
  also have &amp;quot;… = (inversa (a#xs))@ys&amp;quot; &lt;br /&gt;
    by (simp only: inversa.simps(2))&lt;br /&gt;
  finally show ?thesis &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma inversaAcAux_es_inversa:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  fix ys :: &amp;quot;&amp;#039;b list&amp;quot;&lt;br /&gt;
  show &amp;quot;inversaAcAux [] ys = (inversa [])@ys&amp;quot; &lt;br /&gt;
    by (simp only: inversaAcAux.simps(1)&lt;br /&gt;
                   inversa.simps(1)&lt;br /&gt;
                   append.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix a :: &amp;quot;&amp;#039;b&amp;quot; and xs :: &amp;quot;&amp;#039;b list&amp;quot;&lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; &lt;br /&gt;
      by (simp only: inversaAcAux.simps(2))&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; &lt;br /&gt;
      using HI by (simp only:)&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; &lt;br /&gt;
      by (rule auxiliar) &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; &lt;br /&gt;
      by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 21. (p. 43) Demostrar que &lt;br /&gt;
     inversaAc xs = inversa xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  apply (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  by (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text ‹Comentario de la demostración anterior:&lt;br /&gt;
  · &amp;quot;(simp add: inversaAcAux_es_inversa inversaAc_def)&amp;quot; es el método de &lt;br /&gt;
    demostración por simplificación usando como regla de simplificación &lt;br /&gt;
    las propiedades inversaAcAux_es_inversa e inversaAc_def. ›&lt;br /&gt;
 &lt;br /&gt;
section ‹Demostración por inducción para funciones de orden superior ›&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 22. Definir la función&lt;br /&gt;
     sum :: nat list ⇒ nat&lt;br /&gt;
  tal que (sum xs) es la suma de los elementos de xs. Por ejemplo,&lt;br /&gt;
     sum [3,2,5] = 10&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun sum :: &amp;quot;nat list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sum []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;sum (x#xs) = x + sum xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sum [3,2,5] = 10&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 23. Definir la función&lt;br /&gt;
     map :: (&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&lt;br /&gt;
  tal que (map f xs) es la lista obtenida aplicando la función f a los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     map (λx. 2*x) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map ((*) 2) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map ((+) 2)   [3::nat,2,5] = [5,4,7]&lt;br /&gt;
  ------------------------------------------------------------------ ›&lt;br /&gt;
&lt;br /&gt;
fun map :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&amp;quot; where&lt;br /&gt;
  &amp;quot;map f []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;map f (x#xs) = (f x) # map f xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;map (λx. 2*x) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map ((*) 2)   [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map ((+) 2)   [3::nat,2,5] = [5,4,7]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 24. (p. 45) Demostrar que &lt;br /&gt;
     sum (map ((*) 2) xs) = 2 * (sum xs)&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. sum (map (( * ) 2) []) = 2 * sum []&lt;br /&gt;
        2. ⋀a xs. sum (map (( * ) 2) xs) = 2 * sum xs ⟹&lt;br /&gt;
                  sum (map (( * ) 2) (a # xs)) = 2 * sum (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map ((*) 2) []) = 2 * (sum [])&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map ((*) 2) (a#xs)) = sum ((2*a)#(map ((*) 2) xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 2*a + sum (map ((*) 2) xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 2*a + 2*(sum xs)&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = 2*(a + sum xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;sum (map ((*) 2) (a#xs)) = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map ((*) 2) []) = 2 * (sum [])&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(1)&lt;br /&gt;
                   sum.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map ((*) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map ((*) 2) (a#xs)) = sum ((2*a)#(map ((*) 2) xs))&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 2*a + sum (map ((*) 2) xs)&amp;quot; &lt;br /&gt;
    by (simp only: sum.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 2*a + 2*(sum xs)&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = 2*(a + sum xs)&amp;quot; &lt;br /&gt;
    find_theorems &amp;quot;_ * (_ + _)&amp;quot;&lt;br /&gt;
    by (simp only: add_mult_distrib2)&lt;br /&gt;
  also have &amp;quot;… = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by (simp only: sum.simps(2))&lt;br /&gt;
  finally show &amp;quot;sum (map ((*) 2) (a#xs)) = 2*(sum (a#xs))&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹ --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 25. (p. 48) Demostrar que &lt;br /&gt;
     longitud (map f xs) = longitud xs&lt;br /&gt;
  ------------------------------------------------------------------- ›&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. longitud (map f []) = longitud []&lt;br /&gt;
        2. ⋀a xs. longitud (map f xs) = longitud xs ⟹&lt;br /&gt;
                   longitud (map f (a # xs)) = longitud (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (map f xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs&amp;quot; &lt;br /&gt;
    using HI by simp&lt;br /&gt;
  also have &amp;quot;… = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa detallada es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(1)&lt;br /&gt;
                   longitud.simps(1))&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; &lt;br /&gt;
    by (simp only: map.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud (map f xs)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + longitud xs&amp;quot; &lt;br /&gt;
    using HI by (simp only:)&lt;br /&gt;
  also have &amp;quot;… = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by (simp only: longitud.simps(2))&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section ‹Referencias›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  · J.A. Alonso. &amp;quot;Razonamiento sobre programas&amp;quot; http://goo.gl/R06O3&lt;br /&gt;
  · G. Hutton. &amp;quot;Programming in Haskell&amp;quot;. Cap. 13 &amp;quot;Reasoning about&lt;br /&gt;
    programms&amp;quot;. &lt;br /&gt;
  · S. Thompson. &amp;quot;Haskell: the Craft of Functional Programming, 3rd&lt;br /&gt;
    Edition. Cap. 8 &amp;quot;Reasoning about programms&amp;quot;. &lt;br /&gt;
  · L. Paulson. &amp;quot;ML for the Working Programmer, 2nd Edition&amp;quot;. Cap. 6. &lt;br /&gt;
    &amp;quot;Reasoning about functional programs&amp;quot;. &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Programaci%C3%B3n_funcional_en_Isabelle/HOL&amp;diff=817</id>
		<title>Programación funcional en Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Programaci%C3%B3n_funcional_en_Isabelle/HOL&amp;diff=817"/>
		<updated>2020-04-01T19:03:10Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 5 Programación funcional en Isabelle›&lt;br /&gt;
&lt;br /&gt;
theory T5_Programacion_funcional_en_Isabelle&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section ‹Introducción›&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se presenta el lenguaje funcional que está&lt;br /&gt;
  incluido en Isabelle. El lenguaje funcional es muy parecido a&lt;br /&gt;
  Haskell.›&lt;br /&gt;
&lt;br /&gt;
section ‹Números naturales, enteros y booleanos›&lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle están definidos los número naturales con la sintaxis&lt;br /&gt;
  de Peano usando dos constructores: 0 (cero) y Suc (el sucesor).&lt;br /&gt;
&lt;br /&gt;
  Los números como el 1 son abreviaturas de los correspondientes en la&lt;br /&gt;
  notación de Peano, en este caso &amp;quot;Suc 0&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
  El tipo de los números naturales es nat. &lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, el siguiente del 0 es el 1.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;Suc 0&amp;quot;  &lt;br /&gt;
(* ↝ &amp;quot;1&amp;quot; :: &amp;quot;nat&amp;quot;*)&lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle está definida la suma de los números naturales:&lt;br /&gt;
  (x + y) es la suma de x e y.&lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, la suma de los números naturales 1 y 2 es el número&lt;br /&gt;
  natural 3.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(1::nat) + 2&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;3&amp;quot; :: &amp;quot;nat&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(1::nat) + 2 = 3&amp;quot;&lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *) &lt;br /&gt;
&lt;br /&gt;
text ‹La notación del par de dos puntos se usa para asignar un tipo a&lt;br /&gt;
  un término (por ejemplo, (1::nat) significa que se considera que 1 es&lt;br /&gt;
  un número natural).   &lt;br /&gt;
&lt;br /&gt;
  En Isabelle está definida el producto de los números naturales:&lt;br /&gt;
  (x * y) es el producto de x e y.&lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, el producto de los números naturales 2 y 3 es el número&lt;br /&gt;
  natural 6.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(2::nat) * 3&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;6&amp;quot; :: &amp;quot;nat&amp;quot;*)&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(2::nat) * 3 = 6&amp;quot;&lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *) &lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle está definida la división de números naturales: &lt;br /&gt;
  (n div m) es el cociente entero de x entre y.&lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, la división natural de 7 entre 3 es 2.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(7::nat) div 3&amp;quot;&lt;br /&gt;
(* ↝ &amp;quot;2&amp;quot; :: &amp;quot;nat&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(7::nat) div 3 = 2&amp;quot;&lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle está definida el resto de división de números&lt;br /&gt;
  naturales: (n mod m) es el resto de dividir n entre m.&lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, el resto de dividir 7 entre 3 es 1.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(7::nat) mod 3&amp;quot;&lt;br /&gt;
(* ↝ &amp;quot;1&amp;quot; :: &amp;quot;nat&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle también están definidos los números enteros. El tipo&lt;br /&gt;
  de los enteros se representa por int.&lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, la suma de 1 y -2 es el número entero -1.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(1::int) + -2&amp;quot;  &lt;br /&gt;
(* ↝ &amp;quot;- 1&amp;quot; :: &amp;quot;int&amp;quot;*)&lt;br /&gt;
&lt;br /&gt;
text ‹Los numerales están sobrecargados. Por ejemplo, el 1 puede ser&lt;br /&gt;
  un natural o un entero, dependiendo del contexto. &lt;br /&gt;
&lt;br /&gt;
  Isabelle resuelve ambigüedades mediante inferencia de tipos.&lt;br /&gt;
&lt;br /&gt;
  A veces, es necesario usar declaraciones de tipo para resolver la&lt;br /&gt;
  ambigüedad.&lt;br /&gt;
&lt;br /&gt;
  En Isabelle están definidos los valores booleanos (True y False), las&lt;br /&gt;
  conectivas (¬, ∧, ∨, ⟶ y ↔) y los cuantificadores (∀ y ∃). &lt;br /&gt;
&lt;br /&gt;
  El tipo de los booleanos es bool.›&lt;br /&gt;
&lt;br /&gt;
text ‹La conjunción de dos fórmulas verdaderas es verdadera.›&lt;br /&gt;
value &amp;quot;True ∧ True&amp;quot;  &lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹La conjunción de un fórmula verdadera y una falsa es falsa.› &lt;br /&gt;
value &amp;quot;True ∧ False&amp;quot;  &lt;br /&gt;
(* ↝ &amp;quot;False&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹La disyunción de una fórmula verdadera y una falsa es&lt;br /&gt;
  verdadera.› &lt;br /&gt;
value &amp;quot;True ∨ False&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹La disyunción de dos fórmulas falsas es falsa.›&lt;br /&gt;
value &amp;quot;False ∨ False&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;False&amp;quot; :: &amp;quot;bool&amp;quot;*)&lt;br /&gt;
&lt;br /&gt;
text ‹La negación de una fórmula verdadera es falsa.›&lt;br /&gt;
value &amp;quot;¬True&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;False&amp;quot; :: &amp;quot;bool&amp;quot;*)&lt;br /&gt;
&lt;br /&gt;
text ‹Una fórmula falsa implica una fórmula verdadera.›&lt;br /&gt;
value &amp;quot;False ⟶ True&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot;*)&lt;br /&gt;
&lt;br /&gt;
text ‹Un lema introduce una proposición seguida de una demostración. &lt;br /&gt;
&lt;br /&gt;
  Isabelle dispone de varios procedimientos automáticos para generar&lt;br /&gt;
  demostraciones, uno de los cuales es el de simplificación (llamado&lt;br /&gt;
  simp). &lt;br /&gt;
&lt;br /&gt;
  El procedimiento simp aplica un conjunto de reglas de reescritura, que&lt;br /&gt;
  inicialmente contiene un gran número de reglas relativas a los objetos&lt;br /&gt;
  definidos.›&lt;br /&gt;
&lt;br /&gt;
text ‹Ej. de simp: Todo elemento es igual a sí mismo.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;∀x. x = x&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text ‹Ej. de simp: Existe un elemento igual a 1.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;∃x. x = 1&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Definiciones no recursivas›&lt;br /&gt;
&lt;br /&gt;
text ‹La disyunción exclusiva de A y B se verifica si una es verdadera&lt;br /&gt;
  y la otra no lo es.›&lt;br /&gt;
&lt;br /&gt;
definition xor :: &amp;quot;bool ⇒ bool ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;xor A B ≡ (A ∧ ¬B) ∨ (¬A ∧ B)&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
text ‹Prop.: La disyunción exclusiva de dos fórmulas verdaderas es&lt;br /&gt;
  falsa. &lt;br /&gt;
&lt;br /&gt;
  Dem.: Por simplificación, usando la definición de la disyunción&lt;br /&gt;
  exclusiva.›&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;xor True True = False&amp;quot;&lt;br /&gt;
  by (simp add: xor_def)&lt;br /&gt;
&lt;br /&gt;
text ‹Se añade la definición de la disyunción exclusiva al conjunto de&lt;br /&gt;
  reglas de simplificación automáticas.›&lt;br /&gt;
&lt;br /&gt;
declare xor_def [simp]&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;xor True False = True&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Definiciones locales›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede asignar valores a variables locales mediante &amp;#039;let&amp;#039; y&lt;br /&gt;
  usarlo en las expresiones dentro de &amp;#039;in&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, si x es el número natural 3, entonces &amp;quot;x*x = 9&amp;quot;.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;let x = 3::nat in x * x&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;9&amp;quot; :: &amp;quot;nat&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
section ‹Pares›&lt;br /&gt;
&lt;br /&gt;
text ‹Un par se representa escribiendo los elementos entre paréntesis&lt;br /&gt;
  y separados por coma.&lt;br /&gt;
  &lt;br /&gt;
  El tipo de los pares es el producto de los tipos.&lt;br /&gt;
  &lt;br /&gt;
  La función fst devuelve el primer elemento de un par y la snd el&lt;br /&gt;
  segundo. &lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, si p es el par de números naturales (2,3), entonces la&lt;br /&gt;
  suma del primer elemento de p y 1 es igual al segundo elemento de&lt;br /&gt;
  p.› &lt;br /&gt;
&lt;br /&gt;
value &amp;quot;let p = (2,3)::nat × nat in fst p + 1 = snd p&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
section ‹Listas›&lt;br /&gt;
&lt;br /&gt;
text ‹Una lista se representa escribiendo los elementos entre&lt;br /&gt;
  corchetes y separados por comas.&lt;br /&gt;
  &lt;br /&gt;
  La lista vacía se representa por [].&lt;br /&gt;
  &lt;br /&gt;
  Todos los elementos de una lista tienen que ser del mismo tipo.&lt;br /&gt;
  &lt;br /&gt;
  El tipo de las listas de elementos del tipo a es (a list).&lt;br /&gt;
  &lt;br /&gt;
  El término (x#xs) representa la lista obtenida añadiendo el elemento x&lt;br /&gt;
  al principio de la lista xs. &lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, la lista obtenida añadiendo sucesivamente a la lista&lt;br /&gt;
  vacía los elementos z, y y x a es [x,y,z].›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;x#(y#(z#[]))&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;[x, y, z]&amp;quot; :: &amp;quot;&amp;#039;a list&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(1::int)#(2#(3#[]))&amp;quot;&lt;br /&gt;
(* ↝ &amp;quot;[1, 2, 3]&amp;quot; :: &amp;quot;int list&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹Funciones de descomposición de listas:&lt;br /&gt;
  · (hd xs) es el primer elemento de la lista xs.&lt;br /&gt;
  · (tl xs) es el resto de la lista xs.&lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, si xs es la lista [a,b,c], entonces el primero de xs es a&lt;br /&gt;
  y el resto de xs es [b,c].› &lt;br /&gt;
&lt;br /&gt;
value &amp;quot;let xs = [a,b,c] in hd xs = a ∧ tl xs = [b,c]&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹(length xs) es la longitud de la lista xs. Por ejemplo, la&lt;br /&gt;
  longitud de la lista [1,2,5] es 3.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;length [1::nat,2,5]&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;3&amp;quot; :: &amp;quot;nat&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹En la página 10 de &amp;quot;What&amp;#039;s in Main&amp;quot; &lt;br /&gt;
  https://isabelle.in.tum.de/dist/Isabelle2018/doc/main.pdf&lt;br /&gt;
  y en la sesión 66 de &amp;quot;Isabelle/HOL — Higher-Order Logic&amp;quot;&lt;br /&gt;
  https://isabelle.in.tum.de/dist/library/HOL/HOL/document.pdf&lt;br /&gt;
  se encuentran más definiciones y propiedades de las listas.›&lt;br /&gt;
&lt;br /&gt;
section ‹Funciones anónimas›&lt;br /&gt;
&lt;br /&gt;
text ‹En Isabelle pueden definirse funciones anónimas.  &lt;br /&gt;
&lt;br /&gt;
  Por ejemplo, el valor de la función que a un número le asigna su doble&lt;br /&gt;
  aplicada a 1 es 2.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;(λx. x + x) 1::nat&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;2&amp;quot; :: &amp;quot;nat&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
section ‹Condicionales›&lt;br /&gt;
&lt;br /&gt;
text ‹El valor absoluto del entero x es x, si &amp;quot;x ≥ 0&amp;quot; y es -x en caso &lt;br /&gt;
  contrario.›&lt;br /&gt;
&lt;br /&gt;
definition absoluto :: &amp;quot;int ⇒ int&amp;quot; where&lt;br /&gt;
  &amp;quot;absoluto x ≡ (if x ≥ 0 then x else -x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo, el valor absoluto de -3 es 3.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;absoluto(-3)&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;3&amp;quot; :: &amp;quot;int&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
text ‹Def.: Un número natural n es un sucesor si es de la forma &lt;br /&gt;
  (Suc m).›&lt;br /&gt;
&lt;br /&gt;
definition es_sucesor :: &amp;quot;nat ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;es_sucesor n ≡ (case n of &lt;br /&gt;
    0     ⇒ False &lt;br /&gt;
  | Suc m ⇒ True)&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
text ‹Ejemplo, el número 3 es sucesor.›&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;es_sucesor 3&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;True&amp;quot; :: &amp;quot;bool&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
section ‹Tipos de datos y definiciones recursivas›&lt;br /&gt;
&lt;br /&gt;
text ‹Una lista de elementos de tipo a es la lista Vacia o se obtiene&lt;br /&gt;
  añadiendo, con Cons, un elemento de tipo a a una lista de elementos de&lt;br /&gt;
  tipo a.› &lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a Lista = Vacia | Cons &amp;#039;a &amp;quot;&amp;#039;a Lista&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text ‹(conc xs ys) es la concatenación de las lista xs e ys. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     conc (Cons a (Cons b Vacia)) (Cons c Vacia)&lt;br /&gt;
     = Cons a (Cons b (Cons c Vacia))&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
fun conc :: &amp;quot;&amp;#039;a Lista ⇒ &amp;#039;a Lista ⇒ &amp;#039;a Lista&amp;quot; where&lt;br /&gt;
  &amp;quot;conc Vacia ys       = ys&amp;quot;&lt;br /&gt;
| &amp;quot;conc (Cons x xs) ys = Cons x (conc xs ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc (Cons a (Cons b Vacia)) (Cons c Vacia)&amp;quot;&lt;br /&gt;
(* ↝ Lista.Cons a (Lista.Cons b (Lista.Cons c Vacia)) *)&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede declarar que acorte los nombres.›&lt;br /&gt;
&lt;br /&gt;
declare [[names_short]]&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc (Cons a (Cons b Vacia)) (Cons c Vacia)&amp;quot;&lt;br /&gt;
(* ↝ Cons a (Cons b (Cons c Vacia) *)&lt;br /&gt;
&lt;br /&gt;
text ‹(suma n) es la suma de los primeros n números naturales. Por&lt;br /&gt;
  ejemplo,&lt;br /&gt;
     suma 3 = 6&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
fun suma :: &amp;quot;nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;suma 0       = 0&amp;quot;&lt;br /&gt;
| &amp;quot;suma (Suc m) = (Suc m) + suma m&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;suma 3&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;6&amp;quot; :: nat *)&lt;br /&gt;
&lt;br /&gt;
text ‹(sumaImpares n) es la suma de los n primeros números impares. &lt;br /&gt;
  Por ejemplo, &lt;br /&gt;
     sumaImpares 3 = 9&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
fun sumaImpares :: &amp;quot;nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sumaImpares 0       = 0&amp;quot;&lt;br /&gt;
| &amp;quot;sumaImpares (Suc n) = (2 * (Suc n) - 1) + sumaImpares n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sumaImpares 3&amp;quot; &lt;br /&gt;
(* ↝ &amp;quot;9&amp;quot; :: nat *)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Ejercicios&amp;diff=816</id>
		<title>Ejercicios</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Ejercicios&amp;diff=816"/>
		<updated>2020-02-20T16:07:55Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta página se encuentran los ejercicios para resolver de manera colaborativa que complementan al [https://www.cs.us.es/~jalonso/cursos/lmf-18/ejercicios/ejercicios-LMF-2018-19.pdf libro de ejercicios].&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 1&amp;#039;&amp;#039;&amp;#039;: Sintaxis y semántica de la lógica proposicional. ([[R1 |Enunciado]])&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 2&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional. ([[R2 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 3&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional (II). ([[R3 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 4&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional con Isabelle ([[R4 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 5&amp;#039;&amp;#039;&amp;#039;: Sintaxis y semántica de la lógica de primer orden. ([[R5 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 6&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R6.thy Deducción natural en lógica de primer orden con Isabelle] ([[R6 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 7&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R7.thy Deducción natural en lógica proposicional con Isabelle basada en tácticas] ([[R7 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 8&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R8.thy Argumentación en lógica de primer orden con Isabelle.] ([[R8 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 9&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R9.thy Programación funcional en Isabelle] ([[R9 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 10&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R10.thy Programación funcional en Isabelle (2)] ([[R10 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 11&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R11.thy Razonamiento sobre programas en Isabelle/HOL] ([[R11 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 12&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R12.thy Recorridos de árboles en Isabelle/HOL] ([[R12 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 13&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R13.thy Definiciones inductivas: clausuras] ([[R13 |Enunciado]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 14&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R14.thy Desarrollo de teorías axiomáticas] ([[R14 |Enunciado]]).&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_proposicional_con_Isabelle/HOL&amp;diff=815</id>
		<title>Deducción natural proposicional con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_proposicional_con_Isabelle/HOL&amp;diff=815"/>
		<updated>2020-02-19T19:39:55Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 2a: Deducción natural proposicional con Isabelle/HOL›&lt;br /&gt;
&lt;br /&gt;
theory T2a_Deduccion_natural_en_logica_proposicional_con_Isabelle&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se presentan los ejemplos del tema de deducción &lt;br /&gt;
  natural proposicional siguiendo la presentación de Huth y Ryan en su &lt;br /&gt;
  libro &amp;quot;Logic in Computer Science&amp;quot; http://goo.gl/qsVpY y, más &lt;br /&gt;
  concretamente, a la forma como se explica en la asignatura de &lt;br /&gt;
  &amp;quot;Lógica informática&amp;quot; (LI) http://goo.gl/AwDiv&lt;br /&gt;
 &lt;br /&gt;
  La página al lado de cada ejemplo indica la página de las &lt;br /&gt;
  transparencias de LI donde se encuentra la demostración.›&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la conjunción›&lt;br /&gt;
&lt;br /&gt;
text ‹  Notas sobre la lógica: Las reglas de la conjunción son&lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  ›&lt;br /&gt;
&lt;br /&gt;
thm conjI&lt;br /&gt;
thm conjunct1&lt;br /&gt;
thm conjunct2&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 1›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 1 (p. 4). Demostrar que&lt;br /&gt;
     p ∧ q, r ⊢ q ∧ r. ›     &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1: &lt;br /&gt;
  &amp;quot;⟦p ∧ q; r⟧ ⟹ q ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (erule conjunct2)&lt;br /&gt;
  apply assumption  &lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;⟦ ... ⟧&amp;quot; para representar las hipótesis,&lt;br /&gt;
  · &amp;quot;;&amp;quot; para separar las hipótesis y&lt;br /&gt;
  · &amp;quot;⟹&amp;quot; para separar las hipótesis de la conclusión.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ∧ q&amp;quot; and&lt;br /&gt;
          2: &amp;quot;r&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;q&amp;quot; using 1 by (rule conjunct2)&lt;br /&gt;
  show 4: &amp;quot;q ∧ r&amp;quot; using 3 2 by (rule conjI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;assumes&amp;quot; para indicar las hipótesis,&lt;br /&gt;
  · &amp;quot;and&amp;quot; para separar las hipótesis,&lt;br /&gt;
  · &amp;quot;shows&amp;quot; para indicar la conclusión,&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;using&amp;quot; para usar hechos en un paso,&lt;br /&gt;
  · &amp;quot;by (rule ..)&amp;quot; para indicar la regla con la que se peueba un hecho,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden dejar implícitas las reglas como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_2:&lt;br /&gt;
  assumes 1: &amp;quot;p ∧ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;r&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;q&amp;quot; using 1 .. &lt;br /&gt;
  show 4: &amp;quot;q ∧ r&amp;quot; using 3 2 ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;..&amp;quot; para indicar que se prueba por la regla correspondiente.›&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden eliminar las etiquetas como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_3:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;q&amp;quot; using assms(1) ..&lt;br /&gt;
  then show &amp;quot;q ∧ r&amp;quot; using assms(2) ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;assms(n)&amp;quot; para indicar la hipótesis n y&lt;br /&gt;
  · &amp;quot;then show&amp;quot; para demostrar la conclusión usando el hecho anterior.&lt;br /&gt;
  Además, no es necesario usar and entre las hipótesis.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_4:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;assms&amp;quot; para indicar las hipótesis y&lt;br /&gt;
  · &amp;quot;by auto&amp;quot; para demostrar la conclusión automáticamente.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede hacer la demostración por razonamiento hacia atrás,&lt;br /&gt;
  como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_5:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
      and &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof (rule conjI)&lt;br /&gt;
  show &amp;quot;q&amp;quot; using assms(1) by (rule conjunct2)&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;r&amp;quot; using assms(2) by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof (rule r)&amp;quot; para indicar que se hará la demostración con la&lt;br /&gt;
    regla r,&lt;br /&gt;
  · &amp;quot;next&amp;quot; para indicar el comienzo de la prueba del siguiente&lt;br /&gt;
    subobjetivo,&lt;br /&gt;
  · &amp;quot;this&amp;quot; para indicar el hecho actual.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden dejar implícitas las reglas como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_6:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;q&amp;quot; using assms(1) ..&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;r&amp;quot; using assms(2) . &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;.&amp;quot; para indicar por el hecho actual.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostraciones automáticas›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_7:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
  using assms by simp&lt;br /&gt;
&lt;br /&gt;
― ‹Se puede acortar como sigue›&lt;br /&gt;
lemma ejemplo_1_8_:&lt;br /&gt;
  &amp;quot;⟦p ∧ q; r⟧ ⟹ q ∧ r&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la doble negación›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Reglas de la doble negación›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de eliminación de la doble negación es&lt;br /&gt;
  · notnotD: ¬¬ P ⟹ P&lt;br /&gt;
&lt;br /&gt;
  Para ajustarnos al tema de LI vamos a introducir la siguiente regla de&lt;br /&gt;
  introducción de la doble negación&lt;br /&gt;
  · notnotI: P ⟹ ¬¬ P&lt;br /&gt;
  aunque, de momento, no detallamos su demostración.›&lt;br /&gt;
&lt;br /&gt;
lemma notnotI [intro!]: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 2›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 2. (p. 5)&lt;br /&gt;
       p, ¬¬(q ∧ r) ⊢ ¬¬p ∧ r ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2: &lt;br /&gt;
  &amp;quot;⟦p; ¬¬(q ∧ r)⟧ ⟹ ¬¬p ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (rule notnotI)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule notnotD)&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_1:&lt;br /&gt;
  assumes 1: &amp;quot;p&amp;quot; and&lt;br /&gt;
          2: &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows      &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;¬¬p&amp;quot; using 1 by (rule notnotI)&lt;br /&gt;
  have 4: &amp;quot;q ∧ r&amp;quot; using 2 by (rule notnotD)&lt;br /&gt;
  have 5: &amp;quot;r&amp;quot; using 4 by (rule conjunct2)&lt;br /&gt;
  show 6: &amp;quot;¬¬p ∧ r&amp;quot; using 3 5 by (rule conjI)&lt;br /&gt;
qed        &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹Se puede eliminar etiquetas y reglas›&lt;br /&gt;
lemma ejemplo_2_2:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬¬p&amp;quot; using assms(1) ..&lt;br /&gt;
  have &amp;quot;q ∧ r&amp;quot; using assms(2) by (rule notnotD)&lt;br /&gt;
  then have &amp;quot;r&amp;quot; ..&lt;br /&gt;
  with ‹¬¬p› show  &amp;quot;¬¬p ∧ r&amp;quot; ..&lt;br /&gt;
qed        &lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · ‹...› para referenciar un hecho y&lt;br /&gt;
  · &amp;quot;with P show Q&amp;quot; para indicar que con el hecho anterior junto con el&lt;br /&gt;
    hecho P se demuestra Q.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_3:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof  (rule conjI)&lt;br /&gt;
  show &amp;quot;¬¬p&amp;quot; using assms(1) by (rule notnotI)&lt;br /&gt;
next&lt;br /&gt;
  have &amp;quot;q ∧ r&amp;quot; using assms(2) by (rule notnotD) &lt;br /&gt;
  then show &amp;quot;r&amp;quot; by (rule conjunct2)&lt;br /&gt;
qed &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede eliminar las reglas en la demostración anterior, como&lt;br /&gt;
  sigue:›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_4:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;¬¬p&amp;quot; using assms(1) ..&lt;br /&gt;
next&lt;br /&gt;
  have &amp;quot;q ∧ r&amp;quot; using assms(2) by (rule notnotD) &lt;br /&gt;
  then show &amp;quot;r&amp;quot; .. &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostraciones automáticas›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_5:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
― ‹Se puede simplificar›&lt;br /&gt;
lemma ejemplo_2_6: &lt;br /&gt;
  &amp;quot;⟦p; ¬¬(q ∧ r)⟧ ⟹ ¬¬p ∧ r&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Regla de eliminación del condicional›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de eliminación del condicional es la regla del modus &lt;br /&gt;
  ponens&lt;br /&gt;
  · mp: ⟦P ⟶ Q; P⟧ ⟹ Q ›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 3›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 3. (p. 6) Demostrar que&lt;br /&gt;
     ¬p ∧ q, ¬p ∧ q ⟶ r ∨ ¬p ⊢ r ∨ ¬p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3: &lt;br /&gt;
  &amp;quot;⟦¬p ∧ q; ¬p ∧ q ⟶ r ∨ ¬p⟧ ⟹ r ∨ ¬p&amp;quot;&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3_1:&lt;br /&gt;
  assumes 1: &amp;quot;¬p ∧ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;¬p ∧ q ⟶ r ∨ ¬p&amp;quot; &lt;br /&gt;
  shows      &amp;quot;r ∨ ¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;r ∨ ¬p&amp;quot; using 2 1 by (rule mp)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3_2:&lt;br /&gt;
  assumes &amp;quot;¬p ∧ q&amp;quot;&lt;br /&gt;
          &amp;quot;¬p ∧ q ⟶ r ∨ ¬p&amp;quot; &lt;br /&gt;
  shows   &amp;quot;r ∨ ¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;r ∨ ¬p&amp;quot; using assms(2,1) ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3_3:&lt;br /&gt;
  &amp;quot;⟦¬p ∧ q; ¬p ∧ q ⟶ r ∨ ¬p⟧ ⟹ r ∨ ¬p&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 4›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 4 (p. 6) Demostrar que&lt;br /&gt;
     p, p ⟶ q, p ⟶ (q ⟶ r) ⊢ r ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4:&lt;br /&gt;
  &amp;quot;⟦p; p ⟶ q; p ⟶ (q ⟶ r)⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4_1:&lt;br /&gt;
  assumes 1: &amp;quot;p&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p ⟶ q&amp;quot; and &lt;br /&gt;
          3: &amp;quot;p ⟶ (q ⟶ r)&amp;quot; &lt;br /&gt;
  shows &amp;quot;r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 4: &amp;quot;q&amp;quot; using 2 1 by (rule mp)&lt;br /&gt;
  have 5: &amp;quot;q ⟶ r&amp;quot; using 3 1 by (rule mp)&lt;br /&gt;
  show 6: &amp;quot;r&amp;quot; using 5 4 by (rule mp)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4_2:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ (q ⟶ r)&amp;quot; &lt;br /&gt;
  shows &amp;quot;r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;q&amp;quot; using assms(2,1) .. &lt;br /&gt;
  have &amp;quot;q ⟶ r&amp;quot; using assms(3,1) ..&lt;br /&gt;
  then show &amp;quot;r&amp;quot; using ‹q› ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4_3:&lt;br /&gt;
  &amp;quot;⟦p; p ⟶ q; p ⟶ (q ⟶ r)⟧ ⟹ r&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Regla derivada del modus tollens›&lt;br /&gt;
&lt;br /&gt;
text ‹Para ajustarnos al tema de LI vamos a introducir la regla del &lt;br /&gt;
  modus tollens&lt;br /&gt;
  · mt: ⟦F ⟶ G; ¬G⟧ ⟹ ¬F &lt;br /&gt;
  aunque, de momento, sin detallar su demostración.›&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 5›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 5 (p. 7). Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r), p, ¬r ⊢ ¬q ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5: &lt;br /&gt;
  &amp;quot;⟦p ⟶ (q ⟶ r); p; ¬r ⟧ ⟹ ¬q&amp;quot;&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ (q ⟶ r)&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p&amp;quot; and &lt;br /&gt;
          3: &amp;quot;¬r&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 4: &amp;quot;q ⟶ r&amp;quot; using 1 2 by (rule mp)&lt;br /&gt;
  show &amp;quot;¬q&amp;quot; using 4 3 by (rule mt)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
          &amp;quot;p&amp;quot;&lt;br /&gt;
          &amp;quot;¬r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;q ⟶ r&amp;quot; using assms(1,2) ..&lt;br /&gt;
  then show &amp;quot;¬q&amp;quot; using assms(3) by (rule mt)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
          &amp;quot;p&amp;quot;&lt;br /&gt;
          &amp;quot;¬r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_4: &lt;br /&gt;
  &amp;quot;⟦p ⟶ (q ⟶ r); p; ¬r ⟧ ⟹ ¬q&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 6›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 6. (p. 7) Demostrar &lt;br /&gt;
     ¬p ⟶ q, ¬q ⊢ p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6: &lt;br /&gt;
  &amp;quot;⟦¬p ⟶ q; ¬q⟧ ⟹ p&amp;quot;&lt;br /&gt;
  apply (drule mt)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notnotD)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6_1:&lt;br /&gt;
  assumes 1: &amp;quot;¬p ⟶ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;¬¬p&amp;quot; using 1 2 by (rule mt)&lt;br /&gt;
  show &amp;quot;p&amp;quot; using 3 by (rule notnotD)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6_2:&lt;br /&gt;
  assumes &amp;quot;¬p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;¬q&amp;quot; &lt;br /&gt;
  shows   &amp;quot;p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬¬p&amp;quot; using assms(1,2) by (rule mt)&lt;br /&gt;
  then show &amp;quot;p&amp;quot; by (rule notnotD)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6_3:&lt;br /&gt;
  &amp;quot;⟦¬p ⟶ q; ¬q⟧ ⟹ p&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 7›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 7. (p. 7) Demostrar&lt;br /&gt;
     p ⟶ ¬q, q ⊢ ¬p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7: &lt;br /&gt;
  &amp;quot;⟦p ⟶ ¬q; q⟧ ⟹ ¬p&amp;quot;  &lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply (erule notnotI)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ ¬q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;¬¬q&amp;quot; using 2 by (rule notnotI)&lt;br /&gt;
  show &amp;quot;¬p&amp;quot; using 1 3 by (rule mt)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ ¬q&amp;quot;&lt;br /&gt;
          &amp;quot;q&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬¬q&amp;quot; using assms(2) by (rule notnotI)&lt;br /&gt;
  with assms(1) show &amp;quot;¬p&amp;quot; by (rule mt)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7_3:&lt;br /&gt;
  &amp;quot;⟦p ⟶ ¬q; q⟧ ⟹ ¬p&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Regla de introducción del condicional›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de introducción del condicional es&lt;br /&gt;
  · impI: (P ⟹ Q) ⟹ P ⟶ Q ›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 8›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 8. (p. 8) Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬q ⟶ ¬p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8: &lt;br /&gt;
  &amp;quot;p ⟶ q ⟹ ¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { assume 2: &amp;quot;¬q&amp;quot;&lt;br /&gt;
    have &amp;quot;¬p&amp;quot; using 1 2 by (rule mt) } &lt;br /&gt;
  then show &amp;quot;¬q ⟶ ¬p&amp;quot; by (rule impI)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;{ ... }&amp;quot; para representar una caja.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;¬q&amp;quot;&lt;br /&gt;
  with assms show &amp;quot;¬p&amp;quot; by (rule mt)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 9›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 9. (p. 9) Demostrar&lt;br /&gt;
     ¬q ⟶ ¬p ⊢ p ⟶ ¬¬q ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_9: &lt;br /&gt;
  &amp;quot;¬q ⟶ ¬p ⟹ p ⟶ ¬¬q&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply (erule notnotI)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_9_1: &lt;br /&gt;
  assumes 1: &amp;quot;¬q ⟶ ¬p&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ ¬¬q&amp;quot;   &lt;br /&gt;
proof -&lt;br /&gt;
  { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
    have 3: &amp;quot;¬¬p&amp;quot; using 2 by (rule notnotI)&lt;br /&gt;
    have &amp;quot;¬¬q&amp;quot; using 1 3 by (rule mt) } &lt;br /&gt;
  then show &amp;quot;p ⟶ ¬¬q&amp;quot; by (rule impI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_9_2:&lt;br /&gt;
  assumes &amp;quot;¬q ⟶ ¬p&amp;quot; &lt;br /&gt;
  shows    &amp;quot;p ⟶ ¬¬q&amp;quot;   &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  then have &amp;quot;¬¬p&amp;quot; by (rule notnotI)&lt;br /&gt;
  with assms show &amp;quot;¬¬q&amp;quot; by (rule mt)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_9_3:&lt;br /&gt;
  assumes &amp;quot;¬q ⟶ ¬p&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ ¬¬q&amp;quot;   &lt;br /&gt;
  using assms&lt;br /&gt;
  by auto &lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 10›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 10 (p. 9). Demostrar&lt;br /&gt;
     ⊢ p ⟶ p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_10: &lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_10_1:&lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { assume 1: &amp;quot;p&amp;quot;&lt;br /&gt;
    have &amp;quot;p&amp;quot; using 1 by this }&lt;br /&gt;
  then show &amp;quot;p ⟶ p&amp;quot; by (rule impI) &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_10_2:&lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_10_3:&lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 11›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 11 (p. 10) Demostrar&lt;br /&gt;
     ⊢ (q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_11:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;  &lt;br /&gt;
  apply (rule impI)+  &lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply (drule mt)&lt;br /&gt;
   apply (erule notnotI)&lt;br /&gt;
  apply (erule notnotD)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_11_1:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { assume 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
    { assume 2: &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
      { assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
        have 4: &amp;quot;¬¬p&amp;quot; using 3 by (rule notnotI)&lt;br /&gt;
        have 5: &amp;quot;¬¬q&amp;quot; using 2 4 by (rule mt)&lt;br /&gt;
        have 6: &amp;quot;q&amp;quot; using 5 by (rule notnotD)&lt;br /&gt;
        have &amp;quot;r&amp;quot; using 1 6 by (rule mp) } &lt;br /&gt;
      then have &amp;quot;p ⟶ r&amp;quot; by (rule impI) } &lt;br /&gt;
    then have &amp;quot;(¬q ⟶ ¬p) ⟶ p ⟶ r&amp;quot; by (rule impI) } &lt;br /&gt;
  then show &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ p ⟶ r)&amp;quot; by (rule impI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración hacia atrás es›&lt;br /&gt;
lemma ejemplo_11_2:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬q ⟶ ¬p) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume 2: &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
    show &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
    proof (rule impI)&lt;br /&gt;
      assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
      have 4: &amp;quot;¬¬p&amp;quot; using 3 by (rule notnotI)&lt;br /&gt;
      have 5: &amp;quot;¬¬q&amp;quot; using 2 4 by (rule mt)&lt;br /&gt;
      have 6: &amp;quot;q&amp;quot; using 5 by (rule notnotD)&lt;br /&gt;
      show &amp;quot;r&amp;quot; using 1 6 by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_11_3:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬q ⟶ ¬p) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume 2: &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
    show &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
      have 4: &amp;quot;¬¬p&amp;quot; using 3 ..&lt;br /&gt;
      have 5: &amp;quot;¬¬q&amp;quot; using 2 4 by (rule mt)&lt;br /&gt;
      have 6: &amp;quot;q&amp;quot; using 5 by (rule notnotD)&lt;br /&gt;
      show &amp;quot;r&amp;quot; using 1 6 ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración sin etiquetas es› &lt;br /&gt;
lemma ejemplo_11_4:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬q ⟶ ¬p) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
    show &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;p&amp;quot;&lt;br /&gt;
      then have &amp;quot;¬¬p&amp;quot; ..&lt;br /&gt;
      with ‹¬q ⟶ ¬p› have &amp;quot;¬¬q&amp;quot; by (rule mt)&lt;br /&gt;
      then have &amp;quot;q&amp;quot; by (rule notnotD)&lt;br /&gt;
      with ‹q ⟶ r› show &amp;quot;r&amp;quot; ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_11_5:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la disyunción›&lt;br /&gt;
&lt;br /&gt;
text ‹Las reglas de la introducción de la disyunción son&lt;br /&gt;
  · disjI1: P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2: Q ⟹ P ∨ Q&lt;br /&gt;
  La regla de elimación de la disyunción es&lt;br /&gt;
  · disjE:  ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R  ›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 12›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 12 (p. 11). Demostrar&lt;br /&gt;
     p ∨ q ⊢ q ∨ p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_12: &lt;br /&gt;
  &amp;quot;p ∨ q ⟹ q ∨ p&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule disjI2)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_12_1:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;p ∨ q&amp;quot; using assms by this&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
    have &amp;quot;q ∨ p&amp;quot; using 2 by (rule disjI2) }&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume 3: &amp;quot;q&amp;quot;&lt;br /&gt;
    have &amp;quot;q ∨ p&amp;quot; using 3 by (rule disjI1) }&lt;br /&gt;
  ultimately show &amp;quot;q ∨ p&amp;quot; by (rule disjE) &lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;moreover&amp;quot; para separar los bloques y&lt;br /&gt;
  · &amp;quot;ultimately&amp;quot; para unir los resultados de los bloques.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada con reglas implícitas es›&lt;br /&gt;
lemma ejemplo_12_2:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  note ‹p ∨ q›&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume &amp;quot;p&amp;quot;&lt;br /&gt;
    then have &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume &amp;quot;q&amp;quot;&lt;br /&gt;
    then have &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
  ultimately show &amp;quot;q ∨ p&amp;quot; ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;note&amp;quot; para copiar un hecho.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_12_3:&lt;br /&gt;
  assumes 1: &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
using 1&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
    show &amp;quot;q ∨ p&amp;quot; using 2 by (rule disjI2) }&lt;br /&gt;
next&lt;br /&gt;
  { assume 3: &amp;quot;q&amp;quot;&lt;br /&gt;
    show &amp;quot;q ∨ p&amp;quot; using 3 by (rule disjI1) }&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_12_4:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
proof &lt;br /&gt;
  { assume  &amp;quot;p&amp;quot;&lt;br /&gt;
    then show &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
next&lt;br /&gt;
  { assume &amp;quot;q&amp;quot;&lt;br /&gt;
    then show &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_12_5:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 13›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 13. (p. 12) Demostrar&lt;br /&gt;
     q ⟶ r ⊢ p ∨ q ⟶ p ∨ r ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_13: &lt;br /&gt;
  &amp;quot;q ⟶ r ⟹ p ∨ q ⟶ p ∨ r&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule disjI2)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_13_1:&lt;br /&gt;
  assumes 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  shows &amp;quot;p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 2: &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  then show &amp;quot;p ∨ r&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    { assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
      show &amp;quot;p ∨ r&amp;quot; using 3 by (rule disjI1) }&lt;br /&gt;
  next&lt;br /&gt;
    { assume 4: &amp;quot;q&amp;quot;&lt;br /&gt;
      have 5: &amp;quot;r&amp;quot; using 1 4 by (rule mp)&lt;br /&gt;
      show &amp;quot;p ∨ r&amp;quot; using 5 by (rule disjI2) }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_13_2:&lt;br /&gt;
  assumes &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  shows &amp;quot;p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  then show &amp;quot;p ∨ r&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    { assume &amp;quot;p&amp;quot;&lt;br /&gt;
      then show &amp;quot;p ∨ r&amp;quot; .. }&lt;br /&gt;
  next&lt;br /&gt;
    { assume &amp;quot;q&amp;quot;&lt;br /&gt;
      have &amp;quot;r&amp;quot; using assms ‹q› ..&lt;br /&gt;
      then show &amp;quot;p ∨ r&amp;quot; .. }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_13_3:&lt;br /&gt;
  assumes &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  shows &amp;quot;p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
section ‹Regla de copia›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 14›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 14 (p. 13). Demostrar&lt;br /&gt;
     ⊢ p ⟶ (q ⟶ p) ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_14: &lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;  &lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_14_1:&lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 1: &amp;quot;p&amp;quot;&lt;br /&gt;
  show &amp;quot;q ⟶ p&amp;quot; &lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;q&amp;quot;&lt;br /&gt;
    show &amp;quot;p&amp;quot; using 1 by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_14_2:&lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  then show &amp;quot;q ⟶ p&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_14_3:&lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la negación›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de eliminación de lo falso es&lt;br /&gt;
  · FalseE: False ⟹ P&lt;br /&gt;
  La regla de eliminación de la negación es&lt;br /&gt;
  · notE: ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  La regla de introducción de la negación es&lt;br /&gt;
  · notI: (P ⟹ False) ⟹ ¬P ›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 15›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 15 (p. 15). Demostrar&lt;br /&gt;
     ¬p ∨ q ⊢ p ⟶ q ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_15: &lt;br /&gt;
  &amp;quot;¬p ∨ q ⟹ p ⟶ q&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_15_1:&lt;br /&gt;
  assumes 1: &amp;quot;¬p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
  note 1&lt;br /&gt;
  then show &amp;quot;q&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    { assume 3: &amp;quot;¬p&amp;quot;&lt;br /&gt;
      show &amp;quot;q&amp;quot; using 3 2 by (rule notE) }&lt;br /&gt;
  next&lt;br /&gt;
    { assume 4: &amp;quot;q&amp;quot;&lt;br /&gt;
      show &amp;quot;q&amp;quot; using 4 by this}&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_15_2:&lt;br /&gt;
  assumes &amp;quot;¬p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  note ‹¬p ∨ q›&lt;br /&gt;
  then show &amp;quot;q&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
    then show &amp;quot;q&amp;quot; using ‹p› .. &lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;q&amp;quot;&lt;br /&gt;
      then show &amp;quot;q&amp;quot; .&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_15_3:&lt;br /&gt;
  assumes &amp;quot;¬p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 16›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 16 (p. 16). Demostrar&lt;br /&gt;
     p ⟶ q, p ⟶ ¬q ⊢ ¬p ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_16: &lt;br /&gt;
  &amp;quot;⟦p ⟶ q; p ⟶ ¬q⟧ ⟹ ¬p&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule mp)+&lt;br /&gt;
    apply assumption+&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_16_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p ⟶ ¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;    &lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
  have 4: &amp;quot;q&amp;quot; using 1 3 by (rule mp)&lt;br /&gt;
  have 5: &amp;quot;¬q&amp;quot; using 2 3 by (rule mp)&lt;br /&gt;
  show False using 5 4 by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_16_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ ¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;    &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  have &amp;quot;q&amp;quot; using assms(1) ‹p› ..&lt;br /&gt;
  have &amp;quot;¬q&amp;quot; using assms(2) ‹p› ..&lt;br /&gt;
  then show False using ‹q› ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_16_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ ¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;    &lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
section ‹Reglas del bicondicional›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de introducción del bicondicional es&lt;br /&gt;
  · iffI: ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P ⟷ Q&lt;br /&gt;
  Las reglas de eliminación del bicondicional son&lt;br /&gt;
  · iffD1: ⟦Q ⟷ P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2: ⟦P ⟷ Q; Q⟧ ⟹ P ›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 17›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 17 (p. 17) Demostrar&lt;br /&gt;
     (p ∧ q) ⟷ (q ∧ p) ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_17_4: &lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;  &lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (rule conjI)&lt;br /&gt;
    apply (erule conjunct2)&lt;br /&gt;
   apply (erule conjunct1)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
    apply (erule conjunct2)&lt;br /&gt;
  apply (erule conjunct1)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_17_1:&lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot; &lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  { assume 1: &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
    have 2: &amp;quot;p&amp;quot; using 1 by (rule conjunct1)&lt;br /&gt;
    have 3: &amp;quot;q&amp;quot; using 1 by (rule conjunct2)&lt;br /&gt;
    show &amp;quot;q ∧ p&amp;quot; using 3 2 by (rule conjI) }&lt;br /&gt;
next&lt;br /&gt;
  { assume 4: &amp;quot;q ∧ p&amp;quot;&lt;br /&gt;
    have 5: &amp;quot;q&amp;quot; using 4 by (rule conjunct1)&lt;br /&gt;
    have 6: &amp;quot;p&amp;quot; using 4 by (rule conjunct2)&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using 6 5 by (rule conjI) }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_17_2:&lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  { assume 1: &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
    have &amp;quot;p&amp;quot; using 1 ..&lt;br /&gt;
    have &amp;quot;q&amp;quot; using 1 ..&lt;br /&gt;
    show &amp;quot;q ∧ p&amp;quot; using ‹q› ‹p› .. }&lt;br /&gt;
next&lt;br /&gt;
  { assume 2: &amp;quot;q ∧ p&amp;quot;&lt;br /&gt;
    have &amp;quot;q&amp;quot; using 2 ..&lt;br /&gt;
    have &amp;quot;p&amp;quot; using 2 ..&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using ‹p› ‹q›  .. }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_17_3:&lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 18›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 18 (p. 18). Demostrar&lt;br /&gt;
     p ⟷ q, p ∨ q ⊢ p ∧ q ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_18_4: &lt;br /&gt;
  &amp;quot;⟦p ⟷ q; p ∨ q⟧ ⟹ p ∧ q&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule conjI)&lt;br /&gt;
    apply assumption&lt;br /&gt;
   apply (erule iffD1)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (erule iffD2)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_18_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟷ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p ∨ q&amp;quot;  &lt;br /&gt;
  shows &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
using 2&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  { assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
    have 4: &amp;quot;q&amp;quot; using 1 3 by (rule iffD1)&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using 3 4 by (rule conjI) }&lt;br /&gt;
next&lt;br /&gt;
  { assume 5: &amp;quot;q&amp;quot;&lt;br /&gt;
    have 6: &amp;quot;p&amp;quot; using 1 5 by (rule iffD2)&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using 6 5 by (rule conjI) }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_18_2:&lt;br /&gt;
  assumes &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;  &lt;br /&gt;
  shows  &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
using assms(2)&lt;br /&gt;
proof&lt;br /&gt;
  { assume &amp;quot;p&amp;quot;&lt;br /&gt;
    with assms(1) have &amp;quot;q&amp;quot; ..&lt;br /&gt;
    with ‹p› show &amp;quot;p ∧ q&amp;quot; .. }&lt;br /&gt;
next&lt;br /&gt;
  { assume &amp;quot;q&amp;quot;&lt;br /&gt;
    with assms(1) have &amp;quot;p&amp;quot; ..&lt;br /&gt;
    then show &amp;quot;p ∧ q&amp;quot; using ‹q› .. }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_18_3:&lt;br /&gt;
  assumes &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;  &lt;br /&gt;
  shows &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
section ‹Reglas derivadas›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla del modus tollens›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 19 (p. 20) Demostrar la regla del modus tollens a partir &lt;br /&gt;
  de las reglas básicas.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_20: &lt;br /&gt;
  &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_20_1:&lt;br /&gt;
  assumes 1: &amp;quot;F ⟶ G&amp;quot; and &lt;br /&gt;
          2: &amp;quot;¬G&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬F&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume 3: &amp;quot;F&amp;quot;&lt;br /&gt;
  have 4: &amp;quot;G&amp;quot; using 1 3 by (rule mp)&lt;br /&gt;
  show False using 2 4 by (rule notE)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_20_2:&lt;br /&gt;
  assumes &amp;quot;F ⟶ G&amp;quot;&lt;br /&gt;
          &amp;quot;¬G&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬F&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;F&amp;quot;&lt;br /&gt;
  with assms(1) have &amp;quot;G&amp;quot; ..&lt;br /&gt;
  with assms(2) show False ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_20_3:&lt;br /&gt;
  assumes &amp;quot;F ⟶ G&amp;quot;&lt;br /&gt;
          &amp;quot;¬G&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬F&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla de la introducción de la doble negación›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 21 (p. 21) Demostrar la regla de introducción de la doble&lt;br /&gt;
  negación a partir de las reglas básicas.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_21: &lt;br /&gt;
  &amp;quot;F ⟹ ¬¬F&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_21_1:&lt;br /&gt;
  assumes 1: &amp;quot;F&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬¬F&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume 2: &amp;quot;¬F&amp;quot;&lt;br /&gt;
  show False using 2 1 by (rule notE)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_21_2:&lt;br /&gt;
  assumes &amp;quot;F&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬¬F&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;¬F&amp;quot;&lt;br /&gt;
  then show False using assms ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_21_3:&lt;br /&gt;
  assumes &amp;quot;F&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬¬F&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla de reducción al absurdo›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de reducción al absurdo en Isabelle se correponde con la&lt;br /&gt;
  regla clásica de contradicción &lt;br /&gt;
  · ccontr: (¬P ⟹ False) ⟹ P ›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ley del tercio excluso›&lt;br /&gt;
&lt;br /&gt;
text ‹La ley del tercio excluso es &lt;br /&gt;
  · excluded_middle: ¬P ∨ P ›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 22 (p. 23). Demostrar la ley del tercio excluso a partir de&lt;br /&gt;
  las reglas básicas.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_22:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
  apply (rule_tac P=&amp;quot;F&amp;quot; in notE)&lt;br /&gt;
   apply (rule notI)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (rule notnotD)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (erule disjI2)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_22_1:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume 1: &amp;quot;¬(F ∨ ¬F)&amp;quot;&lt;br /&gt;
  then show False&lt;br /&gt;
  proof (rule notE)&lt;br /&gt;
    show &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
    proof (rule disjI2)&lt;br /&gt;
      show &amp;quot;¬F&amp;quot;&lt;br /&gt;
      proof (rule notI)&lt;br /&gt;
        assume 2: &amp;quot;F&amp;quot;&lt;br /&gt;
        then have 3: &amp;quot;F ∨ ¬F&amp;quot; by (rule disjI1)&lt;br /&gt;
        show False using 1 3 by (rule notE)&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_22_2:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume &amp;quot;¬(F ∨ ¬F)&amp;quot;&lt;br /&gt;
  then show False&lt;br /&gt;
  proof (rule notE)&lt;br /&gt;
    show &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
    proof (rule disjI2)&lt;br /&gt;
      show &amp;quot;¬F&amp;quot;&lt;br /&gt;
      proof (rule notI)&lt;br /&gt;
        assume &amp;quot;F&amp;quot;&lt;br /&gt;
        then have &amp;quot;F ∨ ¬F&amp;quot; ..&lt;br /&gt;
        with ‹¬(F ∨ ¬F)› show False ..&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_22_3:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 23›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 23 (p. 24). Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬p ∨ q ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_23: &lt;br /&gt;
  &amp;quot;p ⟶ q ⟹ ¬p ∨ q&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;p&amp;quot; in excluded_middle)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule disjI2)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_23_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    { assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; by (rule disjI1) }&lt;br /&gt;
  next&lt;br /&gt;
    { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
      have &amp;quot;q&amp;quot; using 1 2 by (rule mp)&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; by (rule disjI2) }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_23_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    { assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; .. }&lt;br /&gt;
  next&lt;br /&gt;
    { assume &amp;quot;p&amp;quot;&lt;br /&gt;
      with assms have &amp;quot;q&amp;quot; ..&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; .. }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_23_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
section ‹Demostraciones por contradicción›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 24›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 24. Demostrar que &lt;br /&gt;
     ¬p, p ∨ q ⊢ q ›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_24_4: &lt;br /&gt;
  &amp;quot;⟦¬p ; p ∨ q⟧ ⟹ q&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_24_1:&lt;br /&gt;
  assumes &amp;quot;¬p&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  shows   &amp;quot;q&amp;quot;&lt;br /&gt;
using ‹p ∨ q›&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  with assms(1) show &amp;quot;q&amp;quot; by contradiction &lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;q&amp;quot;&lt;br /&gt;
  then show &amp;quot;q&amp;quot; by assumption&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_24_2:&lt;br /&gt;
  assumes &amp;quot;¬p&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  shows &amp;quot;q&amp;quot;&lt;br /&gt;
using ‹p ∨ q›&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  with assms(1) show &amp;quot;q&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;q&amp;quot;&lt;br /&gt;
  then show &amp;quot;q&amp;quot; .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_24_3:&lt;br /&gt;
  assumes &amp;quot;¬p&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  shows &amp;quot;q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Tema_4a&amp;diff=814</id>
		<title>Tema 4a</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Tema_4a&amp;diff=814"/>
		<updated>2020-02-07T20:03:45Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 4a: Deducción natural en lógica de primer orden›&lt;br /&gt;
&lt;br /&gt;
theory T4a_Deduccion_natural_en_logica_de_primer_orden&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹El objetivo de este tema es presentar la deducción natural en &lt;br /&gt;
  lógica de primer orden con Isabelle/HOL. La presentación se &lt;br /&gt;
  basa en los ejemplos de tema 4 del curso LMF que se encuentra &lt;br /&gt;
  en http://goo.gl/uJj8d (que a su vez se basa en el libro de &lt;br /&gt;
  Huth y Ryan &amp;quot;Logic in Computer Science&amp;quot; http://goo.gl/qsVpY ). &lt;br /&gt;
&lt;br /&gt;
  La página al lado de cada ejemplo indica la página de las &lt;br /&gt;
  transparencias de LMF donde se encuentra la demostración.›&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas del cuantificador universal›&lt;br /&gt;
&lt;br /&gt;
text ‹Las reglas del cuantificador universal son&lt;br /&gt;
  · allE:    ⟦∀x. P x; P a ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:    (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 1›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 1 (p. 10). Demostrar que&lt;br /&gt;
     P(c), ∀x. (P(x) ⟶ ¬Q(x)) ⊢ ¬Q(c)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_1a: &lt;br /&gt;
  assumes 1: &amp;quot;P(c)&amp;quot; and&lt;br /&gt;
          2: &amp;quot;∀x. (P(x) ⟶ ¬Q(x))&amp;quot;&lt;br /&gt;
  shows &amp;quot;¬Q(c)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;P(c) ⟶ ¬Q(c)&amp;quot; using 2 by (rule allE)&lt;br /&gt;
  show 4: &amp;quot;¬Q(c)&amp;quot; using 3 1 by (rule mp)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_1b: &lt;br /&gt;
  assumes &amp;quot;P(c)&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. (P(x) ⟶ ¬Q(x))&amp;quot;&lt;br /&gt;
  shows &amp;quot;¬Q(c)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P(c) ⟶ ¬Q(c)&amp;quot; using assms(2) ..&lt;br /&gt;
  then show &amp;quot;¬Q(c)&amp;quot; using assms(1) ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_1c: &lt;br /&gt;
  assumes &amp;quot;P(c)&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. (P(x) ⟶ ¬Q(x))&amp;quot;&lt;br /&gt;
  shows &amp;quot;¬Q(c)&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1d: &lt;br /&gt;
  &amp;quot;⟦P(c); ∀x. (P(x) ⟶ ¬Q(x))⟧ ⟹ ¬Q(c)&amp;quot;&lt;br /&gt;
  apply (erule allE) (* da ⟦P c; P ?x ⟶ ¬ Q ?x⟧ ⟹ ¬ Q c *)&lt;br /&gt;
  apply (erule mp)   (* da P c ⟹ P c *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text ‹Explicaciones&lt;br /&gt;
  apply (erule allE) &lt;br /&gt;
  + Objetivo:       &amp;quot;⟦P(c); ∀x. (P(x) ⟶ ¬Q(x))⟧ ⟹ ¬Q(c)&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;¬Q(c)&amp;quot;, &amp;quot;∀x. (P(x) ⟶ ¬Q(x))&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,    &amp;quot;∀x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?R / ¬Q(c)&lt;br /&gt;
                    ?P x / P(x) ⟶ ¬Q(x) &lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦P c; P ?x ⟶ ¬ Q ?x⟧ ⟹ ¬ Q c&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule mp)   &lt;br /&gt;
  + Objetivo:       &amp;quot;⟦P c; P ?x ⟶ ¬ Q ?x⟧ ⟹ ¬ Q c&amp;quot;&lt;br /&gt;
  + mp:             &amp;quot;⟦?P ⟶ ?Q; ?P⟧ ⟹ ?Q&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;¬ Q c&amp;quot;, &amp;quot;P ?x ⟶ ¬ Q ?x&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?Q&amp;quot;,    &amp;quot;?P ⟶ ?Q&amp;quot;)&lt;br /&gt;
    es              ?Q / ¬ Q c&lt;br /&gt;
                    ?P / P c&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;P c ⟹ P c&amp;quot; &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 2›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 2 (p. 11). Demostrar que&lt;br /&gt;
     ∀x. (P x ⟶ ¬(Q x)), ∀x. P x ⊢ ∀x. ¬(Q x)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_2a: &lt;br /&gt;
  assumes 1: &amp;quot;∀x. (P x ⟶ ¬(Q x))&amp;quot; and&lt;br /&gt;
          2: &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. ¬(Q x)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { fix a&lt;br /&gt;
    have 3: &amp;quot;P a ⟶ ¬(Q a)&amp;quot; using 1 by (rule allE)&lt;br /&gt;
    have 4: &amp;quot;P a&amp;quot; using 2 by (rule allE)&lt;br /&gt;
    have 5: &amp;quot;¬(Q a)&amp;quot; using 3 4 by (rule mp) }&lt;br /&gt;
  then show &amp;quot;∀x. ¬(Q x)&amp;quot; by (rule allI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada hacia atrás es›&lt;br /&gt;
lemma ejemplo_2b: &lt;br /&gt;
  assumes 1: &amp;quot;∀x. (P x ⟶ ¬(Q x))&amp;quot; and&lt;br /&gt;
          2: &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. ¬(Q x)&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix a&lt;br /&gt;
  have 3: &amp;quot;P a ⟶ ¬(Q a)&amp;quot; using 1 by (rule allE)&lt;br /&gt;
  have 4: &amp;quot;P a&amp;quot; using 2 by (rule allE)&lt;br /&gt;
  show 5: &amp;quot;¬(Q a)&amp;quot; using 3 4 by (rule mp) &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_2c: &lt;br /&gt;
  assumes &amp;quot;∀x. (P x ⟶ ¬(Q x))&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. ¬(Q x)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;P a&amp;quot; using assms(2) ..&lt;br /&gt;
  have &amp;quot;P a ⟶ ¬(Q a)&amp;quot; using assms(1) ..&lt;br /&gt;
  then show &amp;quot;¬(Q a)&amp;quot; using ‹P a› ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_2d: &lt;br /&gt;
  assumes &amp;quot;∀x. (P x ⟶ ¬(Q x))&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. ¬(Q x)&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2e: &lt;br /&gt;
  &amp;quot;⟦∀x. (P x ⟶ ¬(Q x)); ∀y. P y⟧ ⟹ ∀z. ¬(Q z)&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* da ⋀z. ⟦P (?x2 z) ⟶ ¬ Q (?x2 z);&lt;br /&gt;
                                 P (?y4 z)⟧&lt;br /&gt;
                                ⟹ ¬ Q z*)&lt;br /&gt;
  apply (erule allE)+ (* da ⋀z. ⟦P (?x2 z) ⟶ ¬ Q (?x2 z);&lt;br /&gt;
                                 P (?y4 z)⟧&lt;br /&gt;
                                ⟹ ¬ Q z *)&lt;br /&gt;
  apply (erule mp)    (* da ⋀z. P (?y4 z) ⟹ P z *)&lt;br /&gt;
  apply assumption    (* da No subgoals! *) &lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas del cuantificador existencial›&lt;br /&gt;
&lt;br /&gt;
text ‹Las reglas del cuantificador existencial son&lt;br /&gt;
  · exI:     P a ⟹ ∃x. P x&lt;br /&gt;
  · exE:     ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  En la regla exE la nueva variable se introduce mediante la declaración &lt;br /&gt;
  &amp;quot;obtain ... where ... by (rule exE)&amp;quot; &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 3›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 3 (p. 12). Demostrar que&lt;br /&gt;
     ∀x. P x ⊢ ∃x. P x&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_3a:&lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;P a&amp;quot; using assms by (rule allE)&lt;br /&gt;
  then show &amp;quot;∃x. P x&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_3b:&lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;P a&amp;quot; using assms ..&lt;br /&gt;
  then show &amp;quot;∃x. P x&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada se puede simplificar›&lt;br /&gt;
lemma ejemplo_3c:&lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
proof (rule exI)&lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;P a&amp;quot; using assms ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada se puede simplificar aún más›&lt;br /&gt;
lemma ejemplo_3d:&lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;P a&amp;quot; using assms ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_3e:&lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3f: &lt;br /&gt;
  &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
  apply (erule allE) (* da P ?x ⟹ ∃y. P y *)&lt;br /&gt;
  apply (erule exI)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 4›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 4 (p. 13). Demostrar&lt;br /&gt;
     ∀x. (P x ⟶ Q x), ∃x. P x ⊢ ∃x. Q x&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_4a:&lt;br /&gt;
  assumes 1: &amp;quot;∀x. (P x ⟶ Q x)&amp;quot; and&lt;br /&gt;
          2: &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. Q x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where 3: &amp;quot;P a&amp;quot; using 2 by (rule exE)&lt;br /&gt;
  have 4: &amp;quot;P a ⟶ Q a&amp;quot; using 1 by (rule allE)&lt;br /&gt;
  have 5: &amp;quot;Q a&amp;quot; using 4 3 by (rule mp)&lt;br /&gt;
  then show 6: &amp;quot;∃x. Q x&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_4b:&lt;br /&gt;
  assumes &amp;quot;∀x. (P x ⟶ Q x)&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. Q x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;P a&amp;quot; using assms(2) ..&lt;br /&gt;
  have &amp;quot;P a ⟶ Q a&amp;quot; using assms(1) ..&lt;br /&gt;
  then have &amp;quot;Q a&amp;quot; using ‹P a› ..&lt;br /&gt;
  then show &amp;quot;∃x. Q x&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_4c:&lt;br /&gt;
  assumes &amp;quot;∀x. (P x ⟶ Q x)&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  shows &amp;quot;∃x. Q x&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4f: &lt;br /&gt;
  &amp;quot;⟦∀x. P x ⟶ Q x; ∃y. P y⟧ ⟹ ∃z. Q z&amp;quot;&lt;br /&gt;
  apply (erule exE)  (* da ⋀y. ⟦∀x. P x ⟶ Q x; P y⟧ ⟹ ∃z. Q z *)&lt;br /&gt;
  apply (erule allE) (* da ⋀y. ⟦P y; P (?x2 y) ⟶ Q (?x2 y)⟧ ⟹ ∃z. Q z *)&lt;br /&gt;
  apply (rule exI)   (* da ⋀y. ⟦P y; P (?x2 y) ⟶ Q (?x2 y)⟧ ⟹ Q (?z4 y) *)&lt;br /&gt;
  apply (erule mp)   (* da ⋀y. P y ⟹ P (?x2 y) *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Demostración de equivalencias›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 5.1›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 5.1 (p. 15). Demostrar&lt;br /&gt;
     ¬∀x. P x  ⊢ ∃x. ¬(P x)›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_5_1a:&lt;br /&gt;
  assumes &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume &amp;quot;¬(∃x. ¬P(x))&amp;quot;&lt;br /&gt;
  have &amp;quot;∀x. P(x)&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    show &amp;quot;P(a)&amp;quot;&lt;br /&gt;
    proof (rule ccontr)&lt;br /&gt;
      assume &amp;quot;¬P(a)&amp;quot;&lt;br /&gt;
      then have &amp;quot;∃x. ¬P(x)&amp;quot; by (rule exI)&lt;br /&gt;
      with ‹¬(∃x. ¬P(x))› show False by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
  with assms show False by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_5_1b:&lt;br /&gt;
  assumes &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume &amp;quot;¬(∃x. ¬P(x))&amp;quot;&lt;br /&gt;
  have &amp;quot;∀x. P(x)&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    fix a&lt;br /&gt;
    show &amp;quot;P(a)&amp;quot;&lt;br /&gt;
    proof (rule ccontr)&lt;br /&gt;
      assume &amp;quot;¬P(a)&amp;quot;&lt;br /&gt;
      then have &amp;quot;∃x. ¬P(x)&amp;quot; ..&lt;br /&gt;
      with ‹¬(∃x. ¬P(x))› show False ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
  with assms show False ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_5_1c:&lt;br /&gt;
  assumes &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_1d: &amp;quot;¬(∀x. P x) ⟹ ∃y. ¬P y&amp;quot;&lt;br /&gt;
  apply (rule ccontr) (* da ⟦¬ (∀x. P x); ∄y. ¬ P y⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)  (* da ∄y. ¬ P y ⟹ ∀x. P x *)&lt;br /&gt;
  apply (rule allI)   (* da ⋀x. ∄y. ¬ P y ⟹ P x *)&lt;br /&gt;
  apply (rule ccontr) (* da ⋀x. ⟦∄y. ¬ P y; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)  (* da ⋀x. ¬ P x ⟹ ∃y. ¬ P y *)&lt;br /&gt;
   apply (erule exI)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 5.2 (p. 16). Demostrar&lt;br /&gt;
     ∃x. ¬(P x)  ⊢ ¬∀x. P x›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_5_2a:&lt;br /&gt;
  assumes &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume &amp;quot;∀x. P(x)&amp;quot;&lt;br /&gt;
  obtain a where &amp;quot;¬P(a)&amp;quot; using assms by (rule exE)&lt;br /&gt;
  have &amp;quot;P(a)&amp;quot; using ‹∀x. P(x)› by (rule allE)&lt;br /&gt;
  with ‹¬P(a)› show False by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_5_2b:&lt;br /&gt;
  assumes &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;∀x. P(x)&amp;quot;&lt;br /&gt;
  obtain a where &amp;quot;¬P(a)&amp;quot; using assms ..&lt;br /&gt;
  have &amp;quot;P(a)&amp;quot; using ‹∀x. P(x)› ..&lt;br /&gt;
  with ‹¬P(a)› show False ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_5_2c:&lt;br /&gt;
  assumes &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 5.3 (p. 17). Demostrar&lt;br /&gt;
     ⊢ ¬∀x. P x  ⟷ ∃x. ¬(P x)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_5_3a:&lt;br /&gt;
  &amp;quot;(¬(∀x. P(x))) ⟷ (∃x. ¬P(x))&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;¬(∀x. P(x))&amp;quot;&lt;br /&gt;
  then show &amp;quot;∃x. ¬P(x)&amp;quot; by (rule ejemplo_5_1a)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. ¬P(x)&amp;quot;&lt;br /&gt;
  then show &amp;quot;¬(∀x. P(x))&amp;quot; by (rule ejemplo_5_2a)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_5_3b:&lt;br /&gt;
  &amp;quot;(¬(∀x. P(x))) ⟷ (∃x. ¬P(x))&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 6.1 (p. 18). Demostrar&lt;br /&gt;
     ∀x. P(x) ∧ Q(x) ⊢  (∀x. P(x)) ∧ (∀x. Q(x))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_6_1a:&lt;br /&gt;
  assumes &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
proof (rule conjI)&lt;br /&gt;
  show &amp;quot;∀x. P(x)&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P(a) ∧ Q(a)&amp;quot; using assms by (rule allE)&lt;br /&gt;
    then show &amp;quot;P(a)&amp;quot; by (rule conjunct1)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;∀x. Q(x)&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P(a) ∧ Q(a)&amp;quot; using assms by (rule allE)&lt;br /&gt;
    then show &amp;quot;Q(a)&amp;quot; by (rule conjunct2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_6_1b:&lt;br /&gt;
  assumes &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;∀x. P(x)&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P(a) ∧ Q(a)&amp;quot; using assms ..&lt;br /&gt;
    then show &amp;quot;P(a)&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;∀x. Q(x)&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P(a) ∧ Q(a)&amp;quot; using assms ..&lt;br /&gt;
    then show &amp;quot;Q(a)&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_6_1c:&lt;br /&gt;
  assumes &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 6.2 (p. 19). Demostrar&lt;br /&gt;
     (∀x. P(x)) ∧ (∀x. Q(x)) ⊢ ∀x. P(x) ∧ Q(x)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_6_2a:&lt;br /&gt;
  assumes &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;∀x. P(x)&amp;quot; using assms by (rule conjunct1)&lt;br /&gt;
  then have &amp;quot;P(a)&amp;quot; by (rule allE)&lt;br /&gt;
  have &amp;quot;∀x. Q(x)&amp;quot; using assms by (rule conjunct2)&lt;br /&gt;
  then have &amp;quot;Q(a)&amp;quot; by (rule allE)&lt;br /&gt;
  with ‹P(a)› show &amp;quot;P(a) ∧ Q(a)&amp;quot; by (rule conjI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_6_2b:&lt;br /&gt;
  assumes &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;∀x. P(x)&amp;quot; using assms ..&lt;br /&gt;
  then have &amp;quot;P(a)&amp;quot; by (rule allE)&lt;br /&gt;
  have &amp;quot;∀x. Q(x)&amp;quot; using assms ..&lt;br /&gt;
  then have &amp;quot;Q(a)&amp;quot; ..&lt;br /&gt;
  with ‹P(a)› show &amp;quot;P(a) ∧ Q(a)&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_6_2c:&lt;br /&gt;
  assumes &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 6.3 (p. 20). Demostrar&lt;br /&gt;
     ⊢ ∀x. P(x) ∧ Q(x) ⟷ (∀x. P(x)) ∧ (∀x. Q(x))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_6_3a:&lt;br /&gt;
  &amp;quot;(∀x. P(x) ∧ Q(x)) ⟷ ((∀x. P(x)) ∧ (∀x. Q(x)))&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot;&lt;br /&gt;
  then show &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot; by (rule ejemplo_6_1a)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;(∀x. P(x)) ∧ (∀x. Q(x))&amp;quot;&lt;br /&gt;
  then show &amp;quot;∀x. P(x) ∧ Q(x)&amp;quot; by (rule ejemplo_6_2a)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 7.1 (p. 21). Demostrar&lt;br /&gt;
     (∃x. P(x)) ∨ (∃x. Q(x)) ⊢ ∃x. P(x) ∨ Q(x)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_7_1a:&lt;br /&gt;
  assumes &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  assume &amp;quot;∃x. P(x)&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P(a)&amp;quot; by (rule exE)&lt;br /&gt;
  then have &amp;quot;P(a) ∨ Q(a)&amp;quot; by (rule disjI1)&lt;br /&gt;
  then show &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot; by (rule exI)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. Q(x)&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;Q(a)&amp;quot; by (rule exE)&lt;br /&gt;
  then have &amp;quot;P(a) ∨ Q(a)&amp;quot; by (rule disjI2)&lt;br /&gt;
  then show &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_7_1b:&lt;br /&gt;
  assumes &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∃x. P(x)&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P(a)&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;P(a) ∨ Q(a)&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. Q(x)&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;Q(a)&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;P(a) ∨ Q(a)&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_7_1c:&lt;br /&gt;
  assumes &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 7.2 (p. 22). Demostrar&lt;br /&gt;
     ∃x. P(x) ∨ Q(x) ⊢ (∃x. P(x)) ∨ (∃x. Q(x))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_7_2a:&lt;br /&gt;
  assumes &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;P(a) ∨ Q(a)&amp;quot; using assms by (rule exE)&lt;br /&gt;
  then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;P(a)&amp;quot;&lt;br /&gt;
    then have &amp;quot;∃x. P(x)&amp;quot; by (rule exI)&lt;br /&gt;
    then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot; by (rule disjI1)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;Q(a)&amp;quot;&lt;br /&gt;
    then have &amp;quot;∃x. Q(x)&amp;quot; by (rule exI)&lt;br /&gt;
    then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot; by (rule disjI2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_7_2b:&lt;br /&gt;
  assumes &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;P(a) ∨ Q(a)&amp;quot; using assms ..&lt;br /&gt;
  then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;P(a)&amp;quot;&lt;br /&gt;
    then have &amp;quot;∃x. P(x)&amp;quot; ..&lt;br /&gt;
    then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot; ..&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;Q(a)&amp;quot;&lt;br /&gt;
    then have &amp;quot;∃x. Q(x)&amp;quot; ..&lt;br /&gt;
    then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_7_2c:&lt;br /&gt;
  assumes &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 7.3 (p. 23). Demostrar&lt;br /&gt;
     ⊢ ((∃x. P(x)) ∨ (∃x. Q(x))) ⟷ (∃x. P(x) ∨ Q(x))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_7_3a:&lt;br /&gt;
  &amp;quot;((∃x. P(x)) ∨ (∃x. Q(x))) ⟷ (∃x. P(x) ∨ Q(x))&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot;&lt;br /&gt;
  then show &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot; by (rule ejemplo_7_1a)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. P(x) ∨ Q(x)&amp;quot;&lt;br /&gt;
  then show &amp;quot;(∃x. P(x)) ∨ (∃x. Q(x))&amp;quot; by (rule ejemplo_7_2a)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_7_3b:&lt;br /&gt;
  &amp;quot;((∃x. P(x)) ∨ (∃x. Q(x))) ⟷ (∃x. P(x) ∨ Q(x))&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 8.1 (p. 24). Demostrar&lt;br /&gt;
     ∃x y. P(x,y) ⊢ ∃y x. P(x,y)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_8_1a:&lt;br /&gt;
  assumes &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. P(a,y)&amp;quot; using assms by (rule exE)&lt;br /&gt;
  then obtain b where &amp;quot;P(a,b)&amp;quot; by (rule exE)&lt;br /&gt;
  then have &amp;quot;∃x. P(x,b)&amp;quot; by (rule exI)&lt;br /&gt;
  then show &amp;quot;∃y x. P(x,y)&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_8_1b:&lt;br /&gt;
  assumes &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. P(a,y)&amp;quot; using assms ..&lt;br /&gt;
  then obtain b where &amp;quot;P(a,b)&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;∃x. P(x,b)&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;∃y x. P(x,y)&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_8_1c:&lt;br /&gt;
  assumes &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 8.2. Demostrar&lt;br /&gt;
     ∃y x. P(x,y) ⊢ ∃x y. P(x,y)›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_8_2a:&lt;br /&gt;
  assumes &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain b where &amp;quot;∃x. P(x,b)&amp;quot; using assms by (rule exE)&lt;br /&gt;
  then obtain a where &amp;quot;P(a,b)&amp;quot; by (rule exE)&lt;br /&gt;
  then have &amp;quot;∃y. P(a,y)&amp;quot; by (rule exI)&lt;br /&gt;
  then show &amp;quot;∃x y. P(x,y)&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_8_2b:&lt;br /&gt;
  assumes &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain b where &amp;quot;∃x. P(x,b)&amp;quot; using assms ..&lt;br /&gt;
  then obtain a where &amp;quot;P(a,b)&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;∃y. P(a,y)&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;∃x y. P(x,y)&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_8_2c:&lt;br /&gt;
  assumes &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 8.3 (p. 25). Demostrar&lt;br /&gt;
     ⊢ (∃x y. P(x,y)) ⟷ (∃y x. P(x,y))›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_8_3a:&lt;br /&gt;
  &amp;quot;(∃x y. P(x,y)) ⟷ (∃y x. P(x,y))&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;∃x y. P(x,y)&amp;quot;&lt;br /&gt;
  then show &amp;quot;∃y x. P(x,y)&amp;quot; by (rule ejemplo_8_1a)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃y x. P(x,y)&amp;quot;&lt;br /&gt;
  then show &amp;quot;∃x y. P(x,y)&amp;quot; by (rule ejemplo_8_2a)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_8_3b:&lt;br /&gt;
  &amp;quot;(∃x y. P(x,y)) ⟷ (∃y x. P(x,y))&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la igualdad›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Las reglas básicas de la igualdad son:&lt;br /&gt;
  · refl:  t = t&lt;br /&gt;
  · subst: ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 9 (p. 27). Demostrar&lt;br /&gt;
     x + 1 = 1 + x, x + 1 &amp;gt; 1 ⟶ x + 1 &amp;gt; 0 ⊢ 1 + x &amp;gt; 1 ⟶ 1 + x &amp;gt; 0&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_9a: &lt;br /&gt;
  assumes &amp;quot;x + 1 = 1 + x&amp;quot; &lt;br /&gt;
          &amp;quot;x + 1 &amp;gt; 1 ⟶ x + 1 &amp;gt; 0&amp;quot;&lt;br /&gt;
  shows   &amp;quot;1 + x &amp;gt; 1 ⟶ 1 + x &amp;gt; 0&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;1 + x &amp;gt; 1 ⟶ 1 + x &amp;gt; 0&amp;quot; using assms by (rule subst)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_9b: &lt;br /&gt;
  assumes &amp;quot;x + 1 = 1 + x&amp;quot; &lt;br /&gt;
          &amp;quot;x + 1 &amp;gt; 1 ⟶ x + 1 &amp;gt; 0&amp;quot;&lt;br /&gt;
  shows   &amp;quot;1 + x &amp;gt; 1 ⟶ 1 + x &amp;gt; 0&amp;quot;&lt;br /&gt;
using assms &lt;br /&gt;
by (rule subst)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_9c: &lt;br /&gt;
  assumes &amp;quot;x + 1 = 1 + x&amp;quot; &lt;br /&gt;
          &amp;quot;x + 1 &amp;gt; 1 ⟶ x + 1 &amp;gt; 0&amp;quot;&lt;br /&gt;
  shows   &amp;quot;1 + x &amp;gt; 1 ⟶ 1 + x &amp;gt; 0&amp;quot;&lt;br /&gt;
using assms &lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 10 (p. 27). Demostrar&lt;br /&gt;
     x = y, y = z ⊢ x = z&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_10a:&lt;br /&gt;
  assumes &amp;quot;x = y&amp;quot; &lt;br /&gt;
          &amp;quot;y = z&amp;quot;&lt;br /&gt;
  shows   &amp;quot;x = z&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;x = z&amp;quot; using assms(2,1) by (rule subst)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_10b: &lt;br /&gt;
  assumes &amp;quot;x = y&amp;quot; &lt;br /&gt;
          &amp;quot;y = z&amp;quot;&lt;br /&gt;
  shows   &amp;quot;x = z&amp;quot;&lt;br /&gt;
using assms(2,1)&lt;br /&gt;
by (rule subst)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_10c: &lt;br /&gt;
  assumes &amp;quot;x = y&amp;quot; &lt;br /&gt;
          &amp;quot;y = z&amp;quot;&lt;br /&gt;
  shows   &amp;quot;x = z&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 11 (p. 28). Demostrar&lt;br /&gt;
     s = t ⊢ t = s&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_11a:&lt;br /&gt;
  assumes &amp;quot;s = t&amp;quot;&lt;br /&gt;
  shows   &amp;quot;t = s&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;s = s&amp;quot; by (rule refl)&lt;br /&gt;
  with assms show &amp;quot;t = s&amp;quot; by (rule subst)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_11b:&lt;br /&gt;
  assumes &amp;quot;s = t&amp;quot;&lt;br /&gt;
  shows   &amp;quot;t = s&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Temas&amp;diff=813</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Temas&amp;diff=813"/>
		<updated>2020-02-07T20:02:36Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta página se encuentra el material (transparencias y teorías) del curso &amp;#039;&amp;#039;Lógica matemática y fundamentos&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
* Tema 1:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-1.pdf Sintaxis y semántica de la lógica proposicional].&lt;br /&gt;
* Tema 2:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-2.pdf Deducción natural proposicional].&lt;br /&gt;
* Tema 2a: [[Deducción natural proposicional con Isabelle/HOL]].&lt;br /&gt;
* Tema 3:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-3.pdf Sintaxis y semántica de la lógica de primer orden].&lt;br /&gt;
* Tema 4:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-4.pdf Deducción natural en lógica de primer orden].&lt;br /&gt;
* Tema 4a: [https://www.glc.us.es/~jalonso/LMF2019/index.php/Tema_4a Deducción natural en lógica de primer orden con Isabelle/HOL].&lt;br /&gt;
* Tema 5:  [[Programación funcional en Isabelle/HOL]].             &lt;br /&gt;
* Tema 6:  [https://www.cs.us.es/~jalonso/cursos/i1m/temas/tema-8.pdf Razonamiento sobre programas].    &lt;br /&gt;
* Tema 6a: [[Razonamiento sobre programas en Isabelle/HOL]].                  &lt;br /&gt;
* Tema 7:  [[Razonamiento por casos y por inducci¢n]].         &lt;br /&gt;
* Tema 8:  [[Razonamiento sobre árboles y bosques]].&lt;br /&gt;
* Tema 9:  [[Definiciones inductivas]].&lt;br /&gt;
* Tema 10: [[Conjuntos, funciones y relaciones]].&lt;br /&gt;
* Tema 11: [[Desarrollo de teorías formalizadas con Isabelle/HOL]].&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_proposicional_con_Isabelle/HOL&amp;diff=812</id>
		<title>Deducción natural proposicional con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_proposicional_con_Isabelle/HOL&amp;diff=812"/>
		<updated>2020-02-07T20:02:03Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter ‹Tema 2a: Deducción natural proposicional con Isabelle/HOL›&lt;br /&gt;
&lt;br /&gt;
theory T2a_Deduccion_natural_en_logica_proposicional_con_Isabelle&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹En este tema se presentan los ejemplos del tema de deducción &lt;br /&gt;
  natural proposicional siguiendo la presentación de Huth y Ryan en su &lt;br /&gt;
  libro &amp;quot;Logic in Computer Science&amp;quot; http://goo.gl/qsVpY y, más &lt;br /&gt;
  concretamente, a la forma como se explica en la asignatura de &lt;br /&gt;
  &amp;quot;Lógica informática&amp;quot; (LI) http://goo.gl/AwDiv&lt;br /&gt;
 &lt;br /&gt;
  La página al lado de cada ejemplo indica la página de las &lt;br /&gt;
  transparencias de LI donde se encuentra la demostración.›&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la conjunción›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 1›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 1 (p. 4). Demostrar que&lt;br /&gt;
     p ∧ q, r ⊢ q ∧ r.&lt;br /&gt;
›     &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_1_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ∧ q&amp;quot; and&lt;br /&gt;
          2: &amp;quot;r&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;q&amp;quot; using 1 by (rule conjunct2)&lt;br /&gt;
  show 4: &amp;quot;q ∧ r&amp;quot; using 3 2 by (rule conjI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;assumes&amp;quot; para indicar las hipótesis,&lt;br /&gt;
  · &amp;quot;and&amp;quot; para separar las hipótesis,&lt;br /&gt;
  · &amp;quot;shows&amp;quot; para indicar la conclusión,&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;using&amp;quot; para usar hechos en un paso,&lt;br /&gt;
  · &amp;quot;by (rule ..)&amp;quot; para indicar la regla con la que se peueba un hecho,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.&lt;br /&gt;
&lt;br /&gt;
  Notas sobre la lógica: Las reglas de la conjunción son&lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden dejar implícitas las reglas como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_2:&lt;br /&gt;
  assumes 1: &amp;quot;p ∧ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;r&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;q&amp;quot; using 1 .. &lt;br /&gt;
  show 4: &amp;quot;q ∧ r&amp;quot; using 3 2 ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;..&amp;quot; para indicar que se prueba por la regla correspondiente.›&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden eliminar las etiquetas como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_3:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;q&amp;quot; using assms(1) ..&lt;br /&gt;
  then show &amp;quot;q ∧ r&amp;quot; using assms(2) ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;assms(n)&amp;quot; para indicar la hipótesis n y&lt;br /&gt;
  · &amp;quot;then show&amp;quot; para demostrar la conclusión usando el hecho anterior.&lt;br /&gt;
  Además, no es necesario usar and entre las hipótesis.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede automatizar la demostración como sigue›&lt;br /&gt;
  &lt;br /&gt;
lemma ejemplo_1_4:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;assms&amp;quot; para indicar las hipótesis y&lt;br /&gt;
  · &amp;quot;by auto&amp;quot; para demostrar la conclusión automáticamente.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede hacer la demostración por razonamiento hacia atrás,&lt;br /&gt;
  como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_5:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
      and &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof (rule conjI)&lt;br /&gt;
  show &amp;quot;q&amp;quot; using assms(1) by (rule conjunct2)&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;r&amp;quot; using assms(2) by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof (rule r)&amp;quot; para indicar que se hará la demostración con la&lt;br /&gt;
    regla r,&lt;br /&gt;
  · &amp;quot;next&amp;quot; para indicar el comienzo de la prueba del siguiente&lt;br /&gt;
    subobjetivo,&lt;br /&gt;
  · &amp;quot;this&amp;quot; para indicar el hecho actual.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se pueden dejar implícitas las reglas como sigue›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_6:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;q&amp;quot; using assms(1) ..&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;r&amp;quot; using assms(2) . &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;.&amp;quot; para indicar por el hecho actual.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostraciones automáticas›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1_7:&lt;br /&gt;
  assumes &amp;quot;p ∧ q&amp;quot; &lt;br /&gt;
          &amp;quot;r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;q ∧ r&amp;quot;     &lt;br /&gt;
  using assms by simp&lt;br /&gt;
&lt;br /&gt;
― ‹Se puede acortar como sigue›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_1_8_:&lt;br /&gt;
  &amp;quot;⟦p ∧ q; r⟧ ⟹ q ∧ r&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;⟦ ... ⟧&amp;quot; para representar las hipótesis,&lt;br /&gt;
  · &amp;quot;;&amp;quot; para separar las hipótesis y&lt;br /&gt;
  · &amp;quot;⟹&amp;quot; para separar las hipótesis de la conclusión.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma ejemplo_1_9: &lt;br /&gt;
  &amp;quot;⟦p ∧ q; r⟧ ⟹ q ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (erule conjunct2)&lt;br /&gt;
  apply assumption  &lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
text ‹Explicaciones:&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
  + Objetivo:         ⟦p ∧ q; r⟧ ⟹ q ∧ r&lt;br /&gt;
  + conjI:            ⟦?P; ?Q⟧ ⟹ ?P ∧ ?Q&lt;br /&gt;
  + Unificador de     q ∧ r&lt;br /&gt;
    y                 ?P ∧ ?Q&lt;br /&gt;
    es                ?P/q, ?Q/r&lt;br /&gt;
  + Nuevos objetivos: ⟦p ∧ q; r⟧ ⟹ q&lt;br /&gt;
                      ⟦p ∧ q; r⟧ ⟹ r  &lt;br /&gt;
&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  + Objetivo:         ⟦p ∧ q; r⟧ ⟹ q&lt;br /&gt;
  + conjunct2:        ?P ∧ ?Q ⟹ ?Q&lt;br /&gt;
  + Unificador de     p ∧ q&lt;br /&gt;
    y                 ?P ∧ ?Q&lt;br /&gt;
    es                ?P/p, ?Q/q&lt;br /&gt;
  + Nuevo objetivo:   Nada  &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la doble negación›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Reglas de la doble negación›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de eliminación de la doble negación es&lt;br /&gt;
  · notnotD: ¬¬ P ⟹ P&lt;br /&gt;
&lt;br /&gt;
  Para ajustarnos al tema de LI vamos a introducir la siguiente regla de&lt;br /&gt;
  introducción de la doble negación&lt;br /&gt;
  · notnotI: P ⟹ ¬¬ P&lt;br /&gt;
  aunque, de momento, no detallamos su demostración.&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
lemma notnotI [intro!]: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 2›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 2. (p. 5)&lt;br /&gt;
       p, ¬¬(q ∧ r) ⊢ ¬¬p ∧ r&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_2_1:&lt;br /&gt;
  assumes 1: &amp;quot;p&amp;quot; and&lt;br /&gt;
          2: &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows      &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;¬¬p&amp;quot; using 1 by (rule notnotI)&lt;br /&gt;
  have 4: &amp;quot;q ∧ r&amp;quot; using 2 by (rule notnotD)&lt;br /&gt;
  have 5: &amp;quot;r&amp;quot; using 4 by (rule conjunct2)&lt;br /&gt;
  show 6: &amp;quot;¬¬p ∧ r&amp;quot; using 3 5 by (rule conjI)&lt;br /&gt;
qed        &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹Se puede eliminar etiquetas y reglas›&lt;br /&gt;
lemma ejemplo_2_2:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬¬p&amp;quot; using assms(1) ..&lt;br /&gt;
  have &amp;quot;q ∧ r&amp;quot; using assms(2) by (rule notnotD)&lt;br /&gt;
  then have &amp;quot;r&amp;quot; ..&lt;br /&gt;
  with ‹¬¬p› show  &amp;quot;¬¬p ∧ r&amp;quot; ..&lt;br /&gt;
qed        &lt;br /&gt;
&lt;br /&gt;
text ‹Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · `...` para referenciar un hecho y&lt;br /&gt;
  · &amp;quot;with P show Q&amp;quot; para indicar que con el hecho anterior junto con el&lt;br /&gt;
    hecho P se demuestra Q.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede demostrar hacia atrás›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_3:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof  (rule conjI)&lt;br /&gt;
  show &amp;quot;¬¬p&amp;quot; using assms(1) by (rule notnotI)&lt;br /&gt;
next&lt;br /&gt;
  have &amp;quot;q ∧ r&amp;quot; using assms(2) by (rule notnotD) &lt;br /&gt;
  then show &amp;quot;r&amp;quot; by (rule conjunct2)&lt;br /&gt;
qed &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
text ‹Se puede eliminar las reglas en la demostración anterior, como&lt;br /&gt;
  sigue:›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_4:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;¬¬p&amp;quot; using assms(1) ..&lt;br /&gt;
next&lt;br /&gt;
  have &amp;quot;q ∧ r&amp;quot; using assms(2) by (rule notnotD) &lt;br /&gt;
  then show &amp;quot;r&amp;quot; .. &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostraciones automáticas›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_2_5:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot; &lt;br /&gt;
          &amp;quot;¬¬(q ∧ r)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬¬p ∧ r&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
― ‹Se puede simplificar›&lt;br /&gt;
lemma ejemplo_2_6: &lt;br /&gt;
  &amp;quot;⟦p; ¬¬(q ∧ r)⟧ ⟹ ¬¬p ∧ r&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_7: &lt;br /&gt;
  &amp;quot;⟦p; ¬¬(q ∧ r)⟧ ⟹ ¬¬p ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (rule notnotI)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule notnotD)&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹Explicaciones:&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
  + Objetivo:         ⟦p; ¬¬(q ∧ r)⟧ ⟹ ¬¬p ∧ r&lt;br /&gt;
  + conjI:            ⟦?P; ?Q⟧ ⟹ ?P ∧ ?Q&lt;br /&gt;
  + Unificador de     ¬¬p ∧ r&lt;br /&gt;
    y                 ?P ∧ ?Q&lt;br /&gt;
    es                ?P/¬¬p, ?Q/r&lt;br /&gt;
  + Nuevos objetivos: ⟦p; ¬ ¬ (q ∧ r)⟧ ⟹ ¬ ¬ p&lt;br /&gt;
                      ⟦p; ¬ ¬ (q ∧ r)⟧ ⟹ r  &lt;br /&gt;
&lt;br /&gt;
  apply (rule notnotI)&lt;br /&gt;
  + Objetivo:         ⟦p; ¬ ¬ (q ∧ r)⟧ ⟹ ¬ ¬ p&lt;br /&gt;
  + notnotI:          ?P ⟹ ¬ ¬ ?P&lt;br /&gt;
  + Unificador de     ¬ ¬ p&lt;br /&gt;
    y                 ¬ ¬ ?P&lt;br /&gt;
    es                ?P/p&lt;br /&gt;
  + Nuevo objetivo:   ⟦p; ¬ ¬ (q ∧ r)⟧ ⟹ p  &lt;br /&gt;
&lt;br /&gt;
  apply (drule notnotD)&lt;br /&gt;
  + Objetivo:         ⟦p; ¬ ¬ (q ∧ r)⟧ ⟹ r&lt;br /&gt;
  + notnotD:          ¬ ¬ ?P ⟹ ?P&lt;br /&gt;
  + Unificador de     ¬ ¬ (q ∧ r)&lt;br /&gt;
    y                 ¬ ¬ ?P&lt;br /&gt;
    es                ?P/(q ∧ r)&lt;br /&gt;
  + Nuevo objetivo:   ⟦p; q ∧ r⟧ ⟹ r  &lt;br /&gt;
&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  + Objetivo:         ⟦p; q ∧ r⟧ ⟹ r&lt;br /&gt;
  + conjunct2:        ?P ∧ ?Q ⟹ ?Q&lt;br /&gt;
  + Unificador de     q ∧ r&lt;br /&gt;
    y                 ?P ∧ ?Q&lt;br /&gt;
    es                ?P/q, ?Q/r&lt;br /&gt;
  + Nuevo objetivo:   Nada  &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
section ‹Regla de eliminación del condicional›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de eliminación del condicional es la regla del modus &lt;br /&gt;
  ponens&lt;br /&gt;
  · mp: ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 3›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 3. (p. 6) Demostrar que&lt;br /&gt;
     ¬p ∧ q, ¬p ∧ q ⟶ r ∨ ¬p ⊢ r ∨ ¬p&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_3_1:&lt;br /&gt;
  assumes 1: &amp;quot;¬p ∧ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;¬p ∧ q ⟶ r ∨ ¬p&amp;quot; &lt;br /&gt;
  shows      &amp;quot;r ∨ ¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;r ∨ ¬p&amp;quot; using 2 1 by (rule mp)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_3_2:&lt;br /&gt;
  assumes &amp;quot;¬p ∧ q&amp;quot;&lt;br /&gt;
          &amp;quot;¬p ∧ q ⟶ r ∨ ¬p&amp;quot; &lt;br /&gt;
  shows   &amp;quot;r ∨ ¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;r ∨ ¬p&amp;quot; using assms(2,1) ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3_3: &lt;br /&gt;
  &amp;quot;⟦¬p ∧ q; ¬p ∧ q ⟶ r ∨ ¬p⟧ ⟹ r ∨ ¬p&amp;quot;&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹Explicaciones:&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  + Objetivo:         ⟦¬p ∧ q; ¬p ∧ q ⟶ r ∨ ¬p⟧ ⟹ r ∨ ¬p&lt;br /&gt;
  + mp:               ⟦?P ⟶ ?Q; ?P⟧ ⟹ ?Q&lt;br /&gt;
  + Unificador de     ¬p ∧ q ⟶ r ∨ ¬p &lt;br /&gt;
    y                 ?P ⟶ ?Q&lt;br /&gt;
    es                ?P/¬p ∧ q, ?Q/r ∨ ¬p&lt;br /&gt;
  + Nuevos objetivos: ¬ p ∧ q ⟹ ¬ p ∧ q  &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3_4:&lt;br /&gt;
  &amp;quot;⟦¬p ∧ q; ¬p ∧ q ⟶ r ∨ ¬p⟧ ⟹ r ∨ ¬p&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 4›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 4 (p. 6) Demostrar que&lt;br /&gt;
     p, p ⟶ q, p ⟶ (q ⟶ r) ⊢ r&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_4_1:&lt;br /&gt;
  assumes 1: &amp;quot;p&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p ⟶ q&amp;quot; and &lt;br /&gt;
          3: &amp;quot;p ⟶ (q ⟶ r)&amp;quot; &lt;br /&gt;
  shows &amp;quot;r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 4: &amp;quot;q&amp;quot; using 2 1 by (rule mp)&lt;br /&gt;
  have 5: &amp;quot;q ⟶ r&amp;quot; using 3 1 by (rule mp)&lt;br /&gt;
  show 6: &amp;quot;r&amp;quot; using 5 4 by (rule mp)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_4_2:&lt;br /&gt;
  assumes &amp;quot;p&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ (q ⟶ r)&amp;quot; &lt;br /&gt;
  shows &amp;quot;r&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;q&amp;quot; using assms(2,1) .. &lt;br /&gt;
  have &amp;quot;q ⟶ r&amp;quot; using assms(3,1) ..&lt;br /&gt;
  then show &amp;quot;r&amp;quot; using ‹q› ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4_3:&lt;br /&gt;
  &amp;quot;⟦p; p ⟶ q; p ⟶ (q ⟶ r)⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4_4:&lt;br /&gt;
  &amp;quot;⟦p; p ⟶ q; p ⟶ (q ⟶ r)⟧ ⟹ r&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
section ‹Regla derivada del modus tollens›&lt;br /&gt;
&lt;br /&gt;
text ‹Para ajustarnos al tema de LI vamos a introducir la regla del &lt;br /&gt;
  modus tollens&lt;br /&gt;
  · mt: ⟦F ⟶ G; ¬G⟧ ⟹ ¬F &lt;br /&gt;
  aunque, de momento, sin detallar su demostración.›&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 5›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 5 (p. 7). Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r), p, ¬r ⊢ ¬q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_5_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ (q ⟶ r)&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p&amp;quot; and &lt;br /&gt;
          3: &amp;quot;¬r&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 4: &amp;quot;q ⟶ r&amp;quot; using 1 2 by (rule mp)&lt;br /&gt;
  show &amp;quot;¬q&amp;quot; using 4 3 by (rule mt)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_5_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
          &amp;quot;p&amp;quot;&lt;br /&gt;
          &amp;quot;¬r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;q ⟶ r&amp;quot; using assms(1,2) ..&lt;br /&gt;
  then show &amp;quot;¬q&amp;quot; using assms(3) by (rule mt)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
          &amp;quot;p&amp;quot;&lt;br /&gt;
          &amp;quot;¬r&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_4: &lt;br /&gt;
  &amp;quot;⟦p ⟶ (q ⟶ r); p; ¬r ⟧ ⟹ ¬q&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_5: &lt;br /&gt;
  &amp;quot;⟦p ⟶ (q ⟶ r); p; ¬r ⟧ ⟹ ¬q&amp;quot;&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 6›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 6. (p. 7) Demostrar &lt;br /&gt;
     ¬p ⟶ q, ¬q ⊢ p&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_6_1:&lt;br /&gt;
  assumes 1: &amp;quot;¬p ⟶ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;¬¬p&amp;quot; using 1 2 by (rule mt)&lt;br /&gt;
  show &amp;quot;p&amp;quot; using 3 by (rule notnotD)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_6_2:&lt;br /&gt;
  assumes &amp;quot;¬p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;¬q&amp;quot; &lt;br /&gt;
  shows   &amp;quot;p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬¬p&amp;quot; using assms(1,2) by (rule mt)&lt;br /&gt;
  then show &amp;quot;p&amp;quot; by (rule notnotD)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6_3:&lt;br /&gt;
  &amp;quot;⟦¬p ⟶ q; ¬q⟧ ⟹ p&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6_4: &lt;br /&gt;
  &amp;quot;⟦¬p ⟶ q; ¬q⟧ ⟹ p&amp;quot;  &lt;br /&gt;
  apply (drule mt)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notnotD)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 7›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 7. (p. 7) Demostrar&lt;br /&gt;
     p ⟶ ¬q, q ⊢ ¬p&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_7_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ ¬q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have 3: &amp;quot;¬¬q&amp;quot; using 2 by (rule notnotI)&lt;br /&gt;
  show &amp;quot;¬p&amp;quot; using 1 3 by (rule mt)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_7_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ ¬q&amp;quot;&lt;br /&gt;
          &amp;quot;q&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬¬q&amp;quot; using assms(2) by (rule notnotI)&lt;br /&gt;
  with assms(1) show &amp;quot;¬p&amp;quot; by (rule mt)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7_3:&lt;br /&gt;
  &amp;quot;⟦p ⟶ ¬q; q⟧ ⟹ ¬p&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7_4: &lt;br /&gt;
  &amp;quot;⟦p ⟶ ¬q; q⟧ ⟹ ¬p&amp;quot;  &lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply (erule notnotI)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Regla de introducción del condicional›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de introducción del condicional es&lt;br /&gt;
  · impI: (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 8›&lt;br /&gt;
&lt;br /&gt;
text ‹  Ejemplo 8. (p. 8) Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬q ⟶ ¬p&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_8_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { assume 2: &amp;quot;¬q&amp;quot;&lt;br /&gt;
    have &amp;quot;¬p&amp;quot; using 1 2 by (rule mt) } &lt;br /&gt;
  then show &amp;quot;¬q ⟶ ¬p&amp;quot; by (rule impI)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;{ ... }&amp;quot; para representar una caja.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_8_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;¬q&amp;quot;&lt;br /&gt;
  with assms show &amp;quot;¬p&amp;quot; by (rule mt)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8_4: &lt;br /&gt;
  &amp;quot;p ⟶ q ⟹ ¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 9›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 9. (p. 9) Demostrar&lt;br /&gt;
     ¬q ⟶ ¬p ⊢ p ⟶ ¬¬q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_9_1: &lt;br /&gt;
  assumes 1: &amp;quot;¬q ⟶ ¬p&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ ¬¬q&amp;quot;   &lt;br /&gt;
proof -&lt;br /&gt;
  { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
    have 3: &amp;quot;¬¬p&amp;quot; using 2 by (rule notnotI)&lt;br /&gt;
    have &amp;quot;¬¬q&amp;quot; using 1 3 by (rule mt) } &lt;br /&gt;
  then show &amp;quot;p ⟶ ¬¬q&amp;quot; by (rule impI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_9_2:&lt;br /&gt;
  assumes &amp;quot;¬q ⟶ ¬p&amp;quot; &lt;br /&gt;
  shows    &amp;quot;p ⟶ ¬¬q&amp;quot;   &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  then have &amp;quot;¬¬p&amp;quot; by (rule notnotI)&lt;br /&gt;
  with assms show &amp;quot;¬¬q&amp;quot; by (rule mt)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_9_3:&lt;br /&gt;
  assumes &amp;quot;¬q ⟶ ¬p&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ ¬¬q&amp;quot;   &lt;br /&gt;
  using assms&lt;br /&gt;
  by auto &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_9_4: &lt;br /&gt;
  &amp;quot;¬q ⟶ ¬p ⟹ p ⟶ ¬¬q&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply (rule notnotI)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 10›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 10 (p. 9). Demostrar&lt;br /&gt;
     ⊢ p ⟶ p&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_10_1:&lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { assume 1: &amp;quot;p&amp;quot;&lt;br /&gt;
    have &amp;quot;p&amp;quot; using 1 by this }&lt;br /&gt;
  then show &amp;quot;p ⟶ p&amp;quot; by (rule impI) &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_10_2:&lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_10_3:&lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_10_4: &lt;br /&gt;
  &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 11›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 11 (p. 10) Demostrar&lt;br /&gt;
     ⊢ (q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_11_1:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { assume 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
    { assume 2: &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
      { assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
        have 4: &amp;quot;¬¬p&amp;quot; using 3 by (rule notnotI)&lt;br /&gt;
        have 5: &amp;quot;¬¬q&amp;quot; using 2 4 by (rule mt)&lt;br /&gt;
        have 6: &amp;quot;q&amp;quot; using 5 by (rule notnotD)&lt;br /&gt;
        have &amp;quot;r&amp;quot; using 1 6 by (rule mp) } &lt;br /&gt;
      then have &amp;quot;p ⟶ r&amp;quot; by (rule impI) } &lt;br /&gt;
    then have &amp;quot;(¬q ⟶ ¬p) ⟶ p ⟶ r&amp;quot; by (rule impI) } &lt;br /&gt;
  then show &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ p ⟶ r)&amp;quot; by (rule impI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración hacia atrás es›&lt;br /&gt;
lemma ejemplo_11_2:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬q ⟶ ¬p) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume 2: &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
    show &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
    proof (rule impI)&lt;br /&gt;
      assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
      have 4: &amp;quot;¬¬p&amp;quot; using 3 by (rule notnotI)&lt;br /&gt;
      have 5: &amp;quot;¬¬q&amp;quot; using 2 4 by (rule mt)&lt;br /&gt;
      have 6: &amp;quot;q&amp;quot; using 5 by (rule notnotD)&lt;br /&gt;
      show &amp;quot;r&amp;quot; using 1 6 by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración hacia atrás con reglas implícitas es›&lt;br /&gt;
lemma ejemplo_11_3:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬q ⟶ ¬p) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume 2: &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
    show &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
      have 4: &amp;quot;¬¬p&amp;quot; using 3 ..&lt;br /&gt;
      have 5: &amp;quot;¬¬q&amp;quot; using 2 4 by (rule mt)&lt;br /&gt;
      have 6: &amp;quot;q&amp;quot; using 5 by (rule notnotD)&lt;br /&gt;
      show &amp;quot;r&amp;quot; using 1 6 ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración sin etiquetas es› &lt;br /&gt;
lemma ejemplo_11_4:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬q ⟶ ¬p) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
    show &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;p&amp;quot;&lt;br /&gt;
      then have &amp;quot;¬¬p&amp;quot; ..&lt;br /&gt;
      with ‹¬q ⟶ ¬p› have &amp;quot;¬¬q&amp;quot; by (rule mt)&lt;br /&gt;
      then have &amp;quot;q&amp;quot; by (rule notnotD)&lt;br /&gt;
      with ‹q ⟶ r› show &amp;quot;r&amp;quot; ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_11_5:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_11_6:&lt;br /&gt;
  &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;  &lt;br /&gt;
  apply (rule impI)+  &lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply (drule mt)&lt;br /&gt;
   apply (rule notnotI)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (rule notnotD)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la disyunción›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Las reglas de la introducción de la disyunción son&lt;br /&gt;
  · disjI1: P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2: Q ⟹ P ∨ Q&lt;br /&gt;
  La regla de elimación de la disyunción es&lt;br /&gt;
  · disjE:  ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 12›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 12 (p. 11). Demostrar&lt;br /&gt;
     p ∨ q ⊢ q ∨ p&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_12_1:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;p ∨ q&amp;quot; using assms by this&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
    have &amp;quot;q ∨ p&amp;quot; using 2 by (rule disjI2) }&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume 3: &amp;quot;q&amp;quot;&lt;br /&gt;
    have &amp;quot;q ∨ p&amp;quot; using 3 by (rule disjI1) }&lt;br /&gt;
  ultimately show &amp;quot;q ∨ p&amp;quot; by (rule disjE) &lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;moreover&amp;quot; para separar los bloques y&lt;br /&gt;
  · &amp;quot;ultimately&amp;quot; para unir los resultados de los bloques.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada con reglas implícitas es›&lt;br /&gt;
lemma ejemplo_12_2:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  note ‹p ∨ q›&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume &amp;quot;p&amp;quot;&lt;br /&gt;
    then have &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
  moreover&lt;br /&gt;
  { assume &amp;quot;q&amp;quot;&lt;br /&gt;
    then have &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
  ultimately show &amp;quot;q ∨ p&amp;quot; ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Nota sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;note&amp;quot; para copiar un hecho.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración hacia atrás es›&lt;br /&gt;
lemma ejemplo_12_3:&lt;br /&gt;
  assumes 1: &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
using 1&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
    show &amp;quot;q ∨ p&amp;quot; using 2 by (rule disjI2) }&lt;br /&gt;
next&lt;br /&gt;
  { assume 3: &amp;quot;q&amp;quot;&lt;br /&gt;
    show &amp;quot;q ∨ p&amp;quot; using 3 by (rule disjI1) }&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada hacia atrás›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración hacia atrás con reglas implícitas es›&lt;br /&gt;
lemma ejemplo_12_4:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
proof &lt;br /&gt;
  { assume  &amp;quot;p&amp;quot;&lt;br /&gt;
    then show &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
next&lt;br /&gt;
  { assume &amp;quot;q&amp;quot;&lt;br /&gt;
    then show &amp;quot;q ∨ p&amp;quot; .. }&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_12_5:&lt;br /&gt;
  assumes &amp;quot;p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;q ∨ p&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_12_6: &lt;br /&gt;
  &amp;quot;p ∨ q ⟹ q ∨ p&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI2)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   apply assumption+ &lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 13›&lt;br /&gt;
&lt;br /&gt;
text ‹&lt;br /&gt;
  Ejemplo 13. (p. 12) Demostrar&lt;br /&gt;
     q ⟶ r ⊢ p ∨ q ⟶ p ∨ r&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es› &lt;br /&gt;
lemma ejemplo_13_1:&lt;br /&gt;
  assumes 1: &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  shows &amp;quot;p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 2: &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  then show &amp;quot;p ∨ r&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    { assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
      show &amp;quot;p ∨ r&amp;quot; using 3 by (rule disjI1) }&lt;br /&gt;
  next&lt;br /&gt;
    { assume 4: &amp;quot;q&amp;quot;&lt;br /&gt;
      have 5: &amp;quot;r&amp;quot; using 1 4 by (rule mp)&lt;br /&gt;
      show &amp;quot;p ∨ r&amp;quot; using 5 by (rule disjI2) }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es› &lt;br /&gt;
lemma ejemplo_13_2:&lt;br /&gt;
  assumes &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  shows &amp;quot;p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  then show &amp;quot;p ∨ r&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    { assume &amp;quot;p&amp;quot;&lt;br /&gt;
      then show &amp;quot;p ∨ r&amp;quot; .. }&lt;br /&gt;
  next&lt;br /&gt;
    { assume &amp;quot;q&amp;quot;&lt;br /&gt;
      have &amp;quot;r&amp;quot; using assms ‹q› ..&lt;br /&gt;
      then show &amp;quot;p ∨ r&amp;quot; .. }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma ejemplo_13_3:&lt;br /&gt;
  assumes &amp;quot;q ⟶ r&amp;quot;&lt;br /&gt;
  shows &amp;quot;p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_13_4: &lt;br /&gt;
  &amp;quot;q ⟶ r ⟹ p ∨ q ⟶ p ∨ r&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (drule mp)&lt;br /&gt;
  prefer 2&lt;br /&gt;
    apply (rule disjI2)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Regla de copia›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 14›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 14 (p. 13). Demostrar&lt;br /&gt;
     ⊢ p ⟶ (q ⟶ p)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_14_1:&lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 1: &amp;quot;p&amp;quot;&lt;br /&gt;
  show &amp;quot;q ⟶ p&amp;quot; &lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;q&amp;quot;&lt;br /&gt;
    show &amp;quot;p&amp;quot; using 1 by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_14_2:&lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  then show &amp;quot;q ⟶ p&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_14_3:&lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_14_4: &lt;br /&gt;
  &amp;quot;p ⟶ (q ⟶ p)&amp;quot;  &lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas de la negación›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de eliminación de lo falso es&lt;br /&gt;
  · FalseE: False ⟹ P&lt;br /&gt;
  La regla de eliminación de la negación es&lt;br /&gt;
  · notE: ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  La regla de introducción de la negación es&lt;br /&gt;
  · notI: (P ⟹ False) ⟹ ¬P&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 15›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 15 (p. 15). Demostrar&lt;br /&gt;
     ¬p ∨ q ⊢ p ⟶ q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_15_1:&lt;br /&gt;
  assumes 1: &amp;quot;¬p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
  note 1&lt;br /&gt;
  then show &amp;quot;q&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    { assume 3: &amp;quot;¬p&amp;quot;&lt;br /&gt;
      show &amp;quot;q&amp;quot; using 3 2 by (rule notE) }&lt;br /&gt;
  next&lt;br /&gt;
    { assume 4: &amp;quot;q&amp;quot;&lt;br /&gt;
      show &amp;quot;q&amp;quot; using 4 by this}&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_15_2:&lt;br /&gt;
  assumes &amp;quot;¬p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  note ‹¬p ∨ q›&lt;br /&gt;
  then show &amp;quot;q&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
    then show &amp;quot;q&amp;quot; using ‹p› .. &lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;q&amp;quot;&lt;br /&gt;
      then show &amp;quot;q&amp;quot; .&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_15_3:&lt;br /&gt;
  assumes &amp;quot;¬p ∨ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_15_4: &lt;br /&gt;
  &amp;quot;¬p ∨ q ⟹ p ⟶ q&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 16›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 16 (p. 16). Demostrar&lt;br /&gt;
     p ⟶ q, p ⟶ ¬q ⊢ ¬p&lt;br /&gt;
›&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_16_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p ⟶ ¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;    &lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
  have 4: &amp;quot;q&amp;quot; using 1 3 by (rule mp)&lt;br /&gt;
  have 5: &amp;quot;¬q&amp;quot; using 2 3 by (rule mp)&lt;br /&gt;
  show False using 5 4 by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_16_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ ¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;    &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  have &amp;quot;q&amp;quot; using assms(1) ‹p› ..&lt;br /&gt;
  have &amp;quot;¬q&amp;quot; using assms(2) ‹p› ..&lt;br /&gt;
  then show False using ‹q› ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_16_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ⟶ ¬q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p&amp;quot;    &lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_16_4: &lt;br /&gt;
  &amp;quot;⟦p ⟶ q; p ⟶ ¬q⟧ ⟹ ¬p&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule mp)+&lt;br /&gt;
    apply assumption+&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
    prefer 2&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas del bicondicional›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de introducción del bicondicional es&lt;br /&gt;
  · iffI: ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P ⟷ Q&lt;br /&gt;
  Las reglas de eliminación del bicondicional son&lt;br /&gt;
  · iffD1: ⟦Q ⟷ P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2: ⟦P ⟷ Q; Q⟧ ⟹ P&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 17›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 17 (p. 17) Demostrar&lt;br /&gt;
     (p ∧ q) ⟷ (q ∧ p)&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_17_1:&lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot; &lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  { assume 1: &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
    have 2: &amp;quot;p&amp;quot; using 1 by (rule conjunct1)&lt;br /&gt;
    have 3: &amp;quot;q&amp;quot; using 1 by (rule conjunct2)&lt;br /&gt;
    show &amp;quot;q ∧ p&amp;quot; using 3 2 by (rule conjI) }&lt;br /&gt;
next&lt;br /&gt;
  { assume 4: &amp;quot;q ∧ p&amp;quot;&lt;br /&gt;
    have 5: &amp;quot;q&amp;quot; using 4 by (rule conjunct1)&lt;br /&gt;
    have 6: &amp;quot;p&amp;quot; using 4 by (rule conjunct2)&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using 6 5 by (rule conjI) }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_17_2:&lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  { assume 1: &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
    have &amp;quot;p&amp;quot; using 1 ..&lt;br /&gt;
    have &amp;quot;q&amp;quot; using 1 ..&lt;br /&gt;
    show &amp;quot;q ∧ p&amp;quot; using ‹q› ‹p› .. }&lt;br /&gt;
next&lt;br /&gt;
  { assume 2: &amp;quot;q ∧ p&amp;quot;&lt;br /&gt;
    have &amp;quot;q&amp;quot; using 2 ..&lt;br /&gt;
    have &amp;quot;p&amp;quot; using 2 ..&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using ‹p› ‹q›  .. }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_17_3:&lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_17_4: &lt;br /&gt;
  &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;  &lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (rule conjI)&lt;br /&gt;
    apply (erule conjunct2)&lt;br /&gt;
   apply (erule conjunct1)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
    apply (erule conjunct2)&lt;br /&gt;
  apply (erule conjunct1)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 18›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 18 (p. 18). Demostrar&lt;br /&gt;
     p ⟷ q, p ∨ q ⊢ p ∧ q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_18_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟷ q&amp;quot; and &lt;br /&gt;
          2: &amp;quot;p ∨ q&amp;quot;  &lt;br /&gt;
  shows &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
using 2&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  { assume 3: &amp;quot;p&amp;quot;&lt;br /&gt;
    have 4: &amp;quot;q&amp;quot; using 1 3 by (rule iffD1)&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using 3 4 by (rule conjI) }&lt;br /&gt;
next&lt;br /&gt;
  { assume 5: &amp;quot;q&amp;quot;&lt;br /&gt;
    have 6: &amp;quot;p&amp;quot; using 1 5 by (rule iffD2)&lt;br /&gt;
    show &amp;quot;p ∧ q&amp;quot; using 6 5 by (rule conjI) }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_18_2:&lt;br /&gt;
  assumes &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;  &lt;br /&gt;
  shows  &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
using assms(2)&lt;br /&gt;
proof&lt;br /&gt;
  { assume &amp;quot;p&amp;quot;&lt;br /&gt;
    with assms(1) have &amp;quot;q&amp;quot; ..&lt;br /&gt;
    with ‹p› show &amp;quot;p ∧ q&amp;quot; .. }&lt;br /&gt;
next&lt;br /&gt;
  { assume &amp;quot;q&amp;quot;&lt;br /&gt;
    with assms(1) have &amp;quot;p&amp;quot; ..&lt;br /&gt;
    then show &amp;quot;p ∧ q&amp;quot; using ‹q› .. }&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_18_3:&lt;br /&gt;
  assumes &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;  &lt;br /&gt;
  shows &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_18_4: &lt;br /&gt;
  &amp;quot;⟦p ⟷ q; p ∨ q⟧ ⟹ p ∧ q&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule conjI)&lt;br /&gt;
    apply assumption&lt;br /&gt;
    apply (erule iffD1)&lt;br /&gt;
    apply assumption&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
    apply (erule iffD2)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Reglas derivadas›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla del modus tollens›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 19 (p. 20) Demostrar la regla del modus tollens a partir &lt;br /&gt;
  de las reglas básicas.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_20_1:&lt;br /&gt;
  assumes 1: &amp;quot;F ⟶ G&amp;quot; and &lt;br /&gt;
          2: &amp;quot;¬G&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬F&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume 3: &amp;quot;F&amp;quot;&lt;br /&gt;
  have 4: &amp;quot;G&amp;quot; using 1 3 by (rule mp)&lt;br /&gt;
  show False using 2 4 by (rule notE)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_20_2:&lt;br /&gt;
  assumes &amp;quot;F ⟶ G&amp;quot;&lt;br /&gt;
          &amp;quot;¬G&amp;quot; &lt;br /&gt;
  shows   &amp;quot;¬F&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;F&amp;quot;&lt;br /&gt;
  with assms(1) have &amp;quot;G&amp;quot; ..&lt;br /&gt;
  with assms(2) show False ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_20_3:&lt;br /&gt;
  assumes &amp;quot;F ⟶ G&amp;quot;&lt;br /&gt;
          &amp;quot;¬G&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬F&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_20_4: &lt;br /&gt;
  &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla de la introducción de la doble negación›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 21 (p. 21) Demostrar la regla de introducción de la doble&lt;br /&gt;
  negación a partir de las reglas básicas.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_21_1:&lt;br /&gt;
  assumes 1: &amp;quot;F&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬¬F&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume 2: &amp;quot;¬F&amp;quot;&lt;br /&gt;
  show False using 2 1 by (rule notE)&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_21_2:&lt;br /&gt;
  assumes &amp;quot;F&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬¬F&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;¬F&amp;quot;&lt;br /&gt;
  then show False using assms ..&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_21_3:&lt;br /&gt;
  assumes &amp;quot;F&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬¬F&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_21_4: &lt;br /&gt;
  &amp;quot;F ⟹ ¬¬F&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection ‹Regla de reducción al absurdo›&lt;br /&gt;
&lt;br /&gt;
text ‹La regla de reducción al absurdo en Isabelle se correponde con la&lt;br /&gt;
  regla clásica de contradicción &lt;br /&gt;
  · ccontr: (¬P ⟹ False) ⟹ P&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ley del tercio excluso›&lt;br /&gt;
&lt;br /&gt;
text ‹La ley del tercio excluso es &lt;br /&gt;
  · excluded_middle: ¬P ∨ P&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 22 (p. 23). Demostrar la ley del tercio excluso a partir de&lt;br /&gt;
  las reglas básicas.›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_22_1:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume 1: &amp;quot;¬(F ∨ ¬F)&amp;quot;&lt;br /&gt;
  then show False&lt;br /&gt;
  proof (rule notE)&lt;br /&gt;
    show &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
    proof (rule disjI2)&lt;br /&gt;
      show &amp;quot;¬F&amp;quot;&lt;br /&gt;
      proof (rule notI)&lt;br /&gt;
        assume 2: &amp;quot;F&amp;quot;&lt;br /&gt;
        then have 3: &amp;quot;F ∨ ¬F&amp;quot; by (rule disjI1)&lt;br /&gt;
        show False using 1 3 by (rule notE)&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_22_2:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume &amp;quot;¬(F ∨ ¬F)&amp;quot;&lt;br /&gt;
  then show False&lt;br /&gt;
  proof (rule notE)&lt;br /&gt;
    show &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
    proof (rule disjI2)&lt;br /&gt;
      show &amp;quot;¬F&amp;quot;&lt;br /&gt;
      proof (rule notI)&lt;br /&gt;
        assume &amp;quot;F&amp;quot;&lt;br /&gt;
        then have &amp;quot;F ∨ ¬F&amp;quot; ..&lt;br /&gt;
        with ‹¬(F ∨ ¬F)›show False ..&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_22_3:&lt;br /&gt;
  &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 23›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 23 (p. 24). Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬p ∨ q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_23_1:&lt;br /&gt;
  assumes 1: &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    { assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; by (rule disjI1) }&lt;br /&gt;
  next&lt;br /&gt;
    { assume 2: &amp;quot;p&amp;quot;&lt;br /&gt;
      have &amp;quot;q&amp;quot; using 1 2 by (rule mp)&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; by (rule disjI2) }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_23_2:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    { assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; .. }&lt;br /&gt;
  next&lt;br /&gt;
    { assume &amp;quot;p&amp;quot;&lt;br /&gt;
      with assms have &amp;quot;q&amp;quot; ..&lt;br /&gt;
      then show &amp;quot;¬p ∨ q&amp;quot; .. }&lt;br /&gt;
  qed&lt;br /&gt;
qed    &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_23_3:&lt;br /&gt;
  assumes &amp;quot;p ⟶ q&amp;quot; &lt;br /&gt;
  shows &amp;quot;¬p ∨ q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_23_4: &lt;br /&gt;
  &amp;quot;p ⟶ q ⟹ ¬p ∨ q&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;p&amp;quot; in excluded_middle)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (drule mp)&lt;br /&gt;
    prefer 2&lt;br /&gt;
    apply (rule disjI2)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section ‹Demostraciones por contradicción›&lt;br /&gt;
&lt;br /&gt;
subsection ‹Ejemplo 24›&lt;br /&gt;
&lt;br /&gt;
text ‹Ejemplo 24. Demostrar que &lt;br /&gt;
     ¬p, p ∨ q ⊢ q&lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración detallada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejemplo_24_1:&lt;br /&gt;
  assumes &amp;quot;¬p&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  shows   &amp;quot;q&amp;quot;&lt;br /&gt;
using ‹p ∨ q›&lt;br /&gt;
proof (rule disjE)&lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  with assms(1) show &amp;quot;q&amp;quot; by contradiction &lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;q&amp;quot;&lt;br /&gt;
  then show &amp;quot;q&amp;quot; by assumption&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración estructurada›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejemplo_24_2:&lt;br /&gt;
  assumes &amp;quot;¬p&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  shows &amp;quot;q&amp;quot;&lt;br /&gt;
using ‹p ∨ q›&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;p&amp;quot;&lt;br /&gt;
  with assms(1) show &amp;quot;q&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;q&amp;quot;&lt;br /&gt;
  then show &amp;quot;q&amp;quot; .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración automática›&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejemplo_24_3:&lt;br /&gt;
  assumes &amp;quot;¬p&amp;quot;&lt;br /&gt;
          &amp;quot;p ∨ q&amp;quot;&lt;br /&gt;
  shows &amp;quot;q&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
subsubsection ‹Demostración aplicativa›&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_24_4: &lt;br /&gt;
  &amp;quot;⟦¬p ; p ∨ q⟧ ⟹ q&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_4&amp;diff=811</id>
		<title>Examen 4</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_4&amp;diff=811"/>
		<updated>2019-09-11T11:13:00Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
text ‹Examen de Lógica Matemática y Fundamentos (10 septiembre 2019)›&lt;br /&gt;
&lt;br /&gt;
theory examen_4_10_sep_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹Nota: En las demostraciones se pueden las reglas básicas de &lt;br /&gt;
  deducción natural de la lógica proposicional, de los cuantificadores &lt;br /&gt;
  y de la igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. &lt;br /&gt;
›&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     ((p ⟶ r) ∨ (q ⟶ s)) ⟶ ((p ∧ q) ⟶ (r ∨ s))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;((p ⟶ r) ∨ (q ⟶ s)) ⟶ ((p ∧ q) ⟶ (r ∨ s))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume 1: &amp;quot;(p ⟶ r) ∨ (q ⟶ s)&amp;quot;&lt;br /&gt;
  show &amp;quot;(p ∧ q) ⟶ (r ∨ s)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;p ∧ q&amp;quot;&lt;br /&gt;
    hence &amp;quot;p&amp;quot; by (rule conjunct1)&lt;br /&gt;
    have &amp;quot;q&amp;quot; using `p ∧ q` by (rule conjunct2)&lt;br /&gt;
    note 1&lt;br /&gt;
    then show &amp;quot;r ∨ s&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;p ⟶ r&amp;quot;&lt;br /&gt;
      then have &amp;quot;r&amp;quot; using `p` by (rule mp)&lt;br /&gt;
      then show &amp;quot;r ∨ s&amp;quot; by (rule disjI1)&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;q ⟶ s&amp;quot;&lt;br /&gt;
      then have &amp;quot;s&amp;quot; using `q` by (rule mp)&lt;br /&gt;
      then show &amp;quot;r ∨ s&amp;quot; by (rule disjI2)&lt;br /&gt;
    qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa. *)&lt;br /&gt;
lemma &amp;quot;((p ⟶ r) ∨ (q ⟶ s)) ⟶ ((p ∧ q) ⟶ (r ∨ s))&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   apply (erule mp)&lt;br /&gt;
   apply (erule conjunct1)&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Demostrar por deducción natural que la&lt;br /&gt;
  fórmula ∀x. (∃y. ((P(x,y) ∨ Q(x,x)))) es consecuencia &lt;br /&gt;
  lógica de ∀x. (P(x,x) ∨ ∀y. Q(x,y)).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa. *)&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;∀x. (P(x,x) ∨ (∀y. Q(x,y)))&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. (∃y. (P(x,y) ∨ Q(x,x)))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;P(a,a) ∨ (∀y. Q(a,y))&amp;quot; using assms by (rule allE)&lt;br /&gt;
  then show &amp;quot;∃y. (P(a,y) ∨ Q(a,a))&amp;quot; &lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;P(a,a)&amp;quot;&lt;br /&gt;
    then have &amp;quot;P(a,a) ∨ Q(a,a)&amp;quot; by (rule disjI1)&lt;br /&gt;
    then show &amp;quot;∃y. (P(a,y) ∨ Q(a,a))&amp;quot; by (rule exI)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;∀y. Q(a,y)&amp;quot;&lt;br /&gt;
    then have &amp;quot;Q(a,a)&amp;quot; by (rule allE) &lt;br /&gt;
    then have &amp;quot;P(a,a) ∨ Q(a,a)&amp;quot; by (rule disjI2)&lt;br /&gt;
    then show &amp;quot;∃y. (P(a,y) ∨ Q(a,a))&amp;quot; by (rule exI)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa. *)&lt;br /&gt;
lemma &amp;quot;⟦∀x. (P(x,x) ∨ (∀y. Q(x,y)))⟧ ⟹ ∀x. (∃y. (P(x,y) ∨ Q(x,x)))&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (erule_tac x = x in  allE)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule_tac x = x in exI)&lt;br /&gt;
   apply (rule disjI1, simp)&lt;br /&gt;
  apply (erule_tac x = x in  allE)&lt;br /&gt;
   apply (rule_tac x = x in exI)&lt;br /&gt;
  apply (rule disjI2, simp)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario&lt;br /&gt;
  definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  &lt;br /&gt;
                       | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Se define las funciones&lt;br /&gt;
    fun nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nNodos H         = 0&amp;quot;&lt;br /&gt;
    | &amp;quot;nNodos (N x i d) = 1 + nNodos i + nNodos d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    fun nNodosAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nNodosAaux H         n = n&amp;quot;&lt;br /&gt;
    | &amp;quot;nNodosAaux (N x i d) n = 1 + nNodosAaux i (nNodosAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    definition nNodosA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nNodosA a ≡ nNodosAaux a 0&amp;quot;&lt;br /&gt;
  tales que&lt;br /&gt;
  + (nNodos a) es el número de nodos del árbol a. Por ejemplo, &lt;br /&gt;
       nNodos (N e (N c H H) (N g H H)) = 3&lt;br /&gt;
  + (nNodosAA a) es el número de nodos del árbol a, calculado &lt;br /&gt;
    con la función auxiliar nNodosAaux que usa un acumulador. Por &lt;br /&gt;
    ejemplo, &lt;br /&gt;
       nNodosA (N e (N c H H) (N g H H)) = 3&lt;br /&gt;
 &lt;br /&gt;
  Demostrar estructuradamente (es decir, mediante una demostración &lt;br /&gt;
  declarativa) que las funciones nNodos y nNodosA son equivalentes; &lt;br /&gt;
  es decir,&lt;br /&gt;
     nNodosA a = nNodos a&lt;br /&gt;
&lt;br /&gt;
  Notas: &lt;br /&gt;
  1. Los únicos métodos que se pueden usar son induct, (simp only: ...)&lt;br /&gt;
     y this.&lt;br /&gt;
  2. En las demostraciones por introducción del cuantificador universal&lt;br /&gt;
     hay que explicitar el tipo de las variables introducidas con fix.&lt;br /&gt;
     Por ejemplo, en lugar de   &lt;br /&gt;
          fix x t n&lt;br /&gt;
     hay que escribir&lt;br /&gt;
          fix x :: &amp;#039;a and t :: &amp;quot;&amp;#039;a arbol&amp;quot; and and n :: nat&lt;br /&gt;
  -------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  &lt;br /&gt;
                  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodos H         = 0&amp;quot;&lt;br /&gt;
| &amp;quot;nNodos (N x i d) = 1 + nNodos i + nNodos d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nNodosAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodosAaux H         n = n&amp;quot;&lt;br /&gt;
| &amp;quot;nNodosAaux (N x i d) n = 1 + nNodosAaux i (nNodosAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition nNodosA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodosA a ≡ nNodosAaux a 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;nNodos (N e (N c H H) (N g H H)) = 3&amp;quot;&lt;br /&gt;
value &amp;quot;nNodosA (N e (N c H H) (N g H H)) = 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa. *)&lt;br /&gt;
lemma nNodosA:&lt;br /&gt;
  &amp;quot;nNodosAaux a n = (nNodos a) + n&amp;quot;&lt;br /&gt;
proof (induct a arbitrary: n)&lt;br /&gt;
  fix n&lt;br /&gt;
  have &amp;quot;nNodosAaux H n = n&amp;quot; by (simp only: nNodosAaux.simps(1))&lt;br /&gt;
  also have &amp;quot;… = nNodos H + n&amp;quot; by (simp only: nNodos.simps(1))&lt;br /&gt;
  finally show &amp;quot;nNodosAaux H n = nNodos H + n&amp;quot; by this&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;a and &lt;br /&gt;
      i :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      d :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      n :: nat&lt;br /&gt;
  assume HI1: &amp;quot;⋀n. nNodosAaux i n = nNodos i + n&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;⋀n. nNodosAaux d n = nNodos d + n&amp;quot;&lt;br /&gt;
  have &amp;quot;nNodosAaux (N x i d) n = 1 + nNodosAaux i (nNodosAaux d n)&amp;quot; &lt;br /&gt;
    by (simp only: nNodosAaux.simps(2))&lt;br /&gt;
  also have &amp;quot;… = 1 + nNodosAaux i (nNodos d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI2)&lt;br /&gt;
  also have &amp;quot;… = 1 + nNodos i + (nNodos d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI1)&lt;br /&gt;
  also have &amp;quot;… = nNodos (N x i d) + n&amp;quot; &lt;br /&gt;
    by (simp only: nNodos.simps(2))&lt;br /&gt;
  finally show &amp;quot;nNodosAaux (N x i d) n = nNodos (N x i d) + n&amp;quot;  &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa del lema anterior *)&lt;br /&gt;
lemma &amp;quot;nNodosAaux a n = (nNodos a) + n&amp;quot;&lt;br /&gt;
  apply (induct a arbitrary: n)&lt;br /&gt;
   apply (simp only: nNodosAaux.simps(1))&lt;br /&gt;
   apply (simp only: nNodos.simps(1))&lt;br /&gt;
  apply (simp only: nNodosAaux.simps(2))&lt;br /&gt;
  apply (simp only: nNodos.simps(2))&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;nNodosA a = nNodos a&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;nNodosA a = nNodosAaux a 0&amp;quot; by (simp only: nNodosA_def)&lt;br /&gt;
  also have &amp;quot;… = (nNodos a)&amp;quot; by (simp only: nNodosA)&lt;br /&gt;
  finally show &amp;quot;nNodosA a = nNodos a&amp;quot; by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Demostrar que si en un grupo se cumple la siguente&lt;br /&gt;
  propiedad cancelativa &lt;br /&gt;
     ∀x. ∀y. ∀z. x ⋅ y = z ⋅ x ⟶ y = z&lt;br /&gt;
  entonces el grupo es abeliano.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son (simp only: ...) o &lt;br /&gt;
  rule.&lt;br /&gt;
  ------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa. *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. ∀y. ∀z. x ⋅ y = z ⋅ x ⟶ y = z&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. x ⋅ y = y ⋅ x&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  have &amp;quot;b ⋅ (a ⋅ b) = (b ⋅ a) ⋅ b ⟶ a ⋅ b = b ⋅ a&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;∀y. ∀z. b ⋅ y = z ⋅ b ⟶ y = z&amp;quot; using assms by (rule allE)&lt;br /&gt;
    then have &amp;quot;∀z. b ⋅ (a ⋅ b) = z ⋅ b ⟶ a ⋅ b = z&amp;quot; by (rule allE)&lt;br /&gt;
    then show &amp;quot;b ⋅ (a ⋅ b) = (b ⋅ a) ⋅ b ⟶ a ⋅ b = b ⋅ a&amp;quot;  by (rule allE)&lt;br /&gt;
  qed&lt;br /&gt;
  moreover&lt;br /&gt;
  have &amp;quot;b ⋅ (a ⋅ b) = (b ⋅ a) ⋅ b&amp;quot;  by (simp only: asociativa) &lt;br /&gt;
  ultimately show &amp;quot;a ⋅ b = b ⋅ a&amp;quot; by (rule mp)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa. *)&lt;br /&gt;
lemma&lt;br /&gt;
   &amp;quot;⟦∀x. ∀y. ∀z. x ⋅ y = z ⋅ x ⟶ y = z⟧ ⟹&lt;br /&gt;
    ∀x. ∀y. x ⋅ y = y ⋅ x&amp;quot;&lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
  apply (erule_tac x = y in allE)&lt;br /&gt;
  apply (erule_tac x = &amp;quot;x ⋅ y&amp;quot; in allE)&lt;br /&gt;
  apply (erule_tac x = &amp;quot;y ⋅ x&amp;quot; in allE)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply (simp add: asociativa)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_3&amp;diff=810</id>
		<title>Examen 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_3&amp;diff=810"/>
		<updated>2019-07-08T15:39:59Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;text ‹Examen de Lógica Matemática y Fundamentos (5 julio 2019)›&lt;br /&gt;
&lt;br /&gt;
theory examen_3_05_jul_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹Nota: En las demostraciones se pueden las reglas básicas de &lt;br /&gt;
  deducción natural de la lógica proposicional, de los cuantificadores &lt;br /&gt;
  y de la igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. ›&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     p ∨ (q ⟶ ¬(p ⟷ q))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa. *)&lt;br /&gt;
lemma &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
    have &amp;quot;q ⟶ ¬(p ⟷ q)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;q&amp;quot;&lt;br /&gt;
      show &amp;quot;¬(p ⟷ q)&amp;quot;&lt;br /&gt;
      proof&lt;br /&gt;
        assume &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
        then have &amp;quot;p&amp;quot; using `q` by (rule iffD2)&lt;br /&gt;
        with `¬p` show False by (rule notE)&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
    then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot; by (rule disjI2)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;p&amp;quot;&lt;br /&gt;
    then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot; by (rule disjI1)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa. *)&lt;br /&gt;
lemma &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
  apply (case_tac &amp;quot;p&amp;quot;)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (rule disjI2) &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule iffD2)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Se puede formalizar la teoría de las tallas&lt;br /&gt;
  usando los siguientes símbolos&lt;br /&gt;
     P x       representa que x es de la talla pequeña&lt;br /&gt;
     M x       representa que x es de la talla mediana&lt;br /&gt;
     G x       representa que x es de la talla grande&lt;br /&gt;
     Mayor x y representa que la talla de x es mayor que la de y.&lt;br /&gt;
&lt;br /&gt;
  Los axiomas de las tallas son&lt;br /&gt;
     ∃x. P x&lt;br /&gt;
     ∃x. M x&lt;br /&gt;
     ∃x. G x&lt;br /&gt;
     ∀x y. G x ∧ M y ⟶ Mayor x y&lt;br /&gt;
     ∀x y. M x ∧ P y ⟶ Mayor x y&lt;br /&gt;
     ∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z&lt;br /&gt;
     ∀x. ¬(Mayor x x)&lt;br /&gt;
 &lt;br /&gt;
  Demostrar detalladamente que la fórmula&lt;br /&gt;
      ∀x. ¬(P x) ∨ ¬(M x)&lt;br /&gt;
  es consecuencia de los axiomas de las tallas.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. M x&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. G x&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y. G x ∧ M y ⟶ Mayor x y&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y. M x ∧ P y ⟶ Mayor x y&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ¬(Mayor x x)&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. ¬(P x) ∨ ¬(M x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;¬(P a) ∨ P a&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;¬(P a) ∨ ¬(M a)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    then show &amp;quot;¬(P a) ∨ ¬(M a)&amp;quot; by (rule disjI1)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    have &amp;quot;~(M a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;M a&amp;quot;&lt;br /&gt;
      have &amp;quot;~(Mayor a a)&amp;quot; using assms(7) by (rule allE)&lt;br /&gt;
      moreover&lt;br /&gt;
      have &amp;quot;Mayor a a&amp;quot;&lt;br /&gt;
      proof -&lt;br /&gt;
        have &amp;quot;∀y. M a ∧ P y ⟶ Mayor a y&amp;quot; using assms(5) by (rule allE)&lt;br /&gt;
        then have &amp;quot;M a ∧ P a ⟶ Mayor a a&amp;quot;  by (rule allE)&lt;br /&gt;
        moreover&lt;br /&gt;
        have &amp;quot;M a ∧ P a&amp;quot; using `M a` `P a` by (rule conjI)&lt;br /&gt;
        ultimately show &amp;quot;Mayor a a&amp;quot;  by (rule mp)&lt;br /&gt;
      qed  &lt;br /&gt;
      ultimately show False by (rule notE) &lt;br /&gt;
    qed&lt;br /&gt;
    then show &amp;quot;¬ P a ∨ ¬ M a&amp;quot; by (rule disjI2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦∃x. P x;&lt;br /&gt;
        ∃x. M x;&lt;br /&gt;
        ∃x. G x;&lt;br /&gt;
        ∀x y. M x ∧ P y ⟶ Mayor x y;&lt;br /&gt;
        ∀x y. G x ∧ M y ⟶ Mayor x y;&lt;br /&gt;
        ∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z;&lt;br /&gt;
        ∀x. ¬(Mayor x x)⟧⟹&lt;br /&gt;
                             ∀x. ¬(P x) ∨ ¬(M x)&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (case_tac &amp;quot;P x&amp;quot;)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (rule disjI1, assumption)&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply (rule conjI, assumption+)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  &lt;br /&gt;
                       | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Se define las funciones&lt;br /&gt;
    fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
    | &amp;quot;nHojas (N x i d) = nHojas i + nHojas d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    fun nHojasAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojasAaux H         n = n + 1&amp;quot;&lt;br /&gt;
    | &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    definition nHojasA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojasA a ≡ nHojasAaux a 0&amp;quot;&lt;br /&gt;
  tales que&lt;br /&gt;
  + (nHojas a) es el número de hojas del árbol a. Por ejemplo, &lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
  + (nHojasAA a) es el número de hojas del árbol a, calculado &lt;br /&gt;
    con la función auxiliar nHojasAaux que usa un acumulador. Por &lt;br /&gt;
    ejemplo, &lt;br /&gt;
       nHojasA (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
 &lt;br /&gt;
  Demostrar estructuradamente (es decir, mediante una demostración &lt;br /&gt;
  declarativa) que las funciones nHojas y nHojasA son equivalentes; &lt;br /&gt;
  es decir,&lt;br /&gt;
     nHojasA a = nHojas a&lt;br /&gt;
&lt;br /&gt;
  Notas: &lt;br /&gt;
  1. Los únicos métodos que se pueden usar son induct, (simp only: ...)&lt;br /&gt;
     y this.&lt;br /&gt;
  2. En las demostraciones por introducción del cuantificador universal&lt;br /&gt;
     hay que explicitar el tipo de las variables introducidas con fix.&lt;br /&gt;
     Por ejemplo, en lugar de   &lt;br /&gt;
          fix x t n&lt;br /&gt;
     hay que escribir&lt;br /&gt;
          fix x :: &amp;#039;a and t :: &amp;quot;&amp;#039;a arbol&amp;quot; and and n :: nat&lt;br /&gt;
  -------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  &lt;br /&gt;
                  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = nHojas i + nHojas d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojasAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojasAaux H         n = n + 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition nHojasA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojasA a ≡ nHojasAaux a 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;nHojas (N e (N c H H) (N g H H)) = 4&amp;quot;&lt;br /&gt;
value &amp;quot;nHojasA (N e (N c H H) (N g H H)) = 4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma nHojasA:&lt;br /&gt;
  &amp;quot;nHojasAaux a n = (nHojas a) + n&amp;quot;&lt;br /&gt;
proof (induct a arbitrary: n)&lt;br /&gt;
  fix n&lt;br /&gt;
  have &amp;quot;nHojasAaux H n = n + 1&amp;quot; by (simp only: nHojasAaux.simps(1))&lt;br /&gt;
  also have &amp;quot;… = nHojas H + n&amp;quot; by (simp only: nHojas.simps(1))&lt;br /&gt;
  finally show &amp;quot;nHojasAaux H n = nHojas H + n&amp;quot; by this&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;a and &lt;br /&gt;
      i :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      d :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      n :: nat&lt;br /&gt;
  assume HI1: &amp;quot;⋀n. nHojasAaux i n = nHojas i + n&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;⋀n. nHojasAaux d n = nHojas d + n&amp;quot;&lt;br /&gt;
  have &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot; &lt;br /&gt;
    by (simp only: nHojasAaux.simps(2))&lt;br /&gt;
  also have &amp;quot;… = nHojasAaux i (nHojas d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI2)&lt;br /&gt;
  also have &amp;quot;… = nHojas i + (nHojas d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI1)&lt;br /&gt;
  also have &amp;quot;… = nHojas (N x i d) + n&amp;quot; &lt;br /&gt;
    by (simp only: nHojas.simps(2))&lt;br /&gt;
  finally show &amp;quot;nHojasAaux (N x i d) n = nHojas (N x i d) + n&amp;quot;  &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa del lema anterior *)&lt;br /&gt;
lemma &amp;quot;nHojasAaux a n = (nHojas a) + n&amp;quot;&lt;br /&gt;
  apply (induct a arbitrary: n)&lt;br /&gt;
   apply (simp only: nHojasAaux.simps(1))&lt;br /&gt;
   apply (simp only: nHojas.simps(1))&lt;br /&gt;
  apply (simp only: nHojasAaux.simps(2))&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;nHojasA a = nHojas a&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;nHojasA a = nHojasAaux a 0&amp;quot; by (simp only: nHojasA_def)&lt;br /&gt;
  also have &amp;quot;… = (nHojas a)&amp;quot; by (simp only: nHojasA)&lt;br /&gt;
  finally show &amp;quot;nHojasA a = nHojas a&amp;quot; by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Demostrar detalladamente que los grupos &lt;br /&gt;
  booleanos son conmutativos; es decir, si G un grupo tal que  &lt;br /&gt;
     x ⋅ x = 1 &lt;br /&gt;
  para todo x de G, entonces&lt;br /&gt;
     x ⋅ y = y ⋅ x &lt;br /&gt;
  para todo x, y de G.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son (simp only: ...) o &lt;br /&gt;
  rule.&lt;br /&gt;
  ------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Una demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. x ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. x ⋅ y = y ⋅ x&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a ⋅ b = b ⋅ a&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(b ⋅ a) ⋅ (b ⋅ a) = 𝟭&amp;quot; by (simp only: assms)&lt;br /&gt;
    then have &amp;quot;b ⋅ ((b ⋅ a) ⋅ (b ⋅ a)) = b ⋅ 𝟭&amp;quot; by (rule arg_cong)&lt;br /&gt;
    then have &amp;quot;b ⋅ ((b ⋅ a) ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
    then have &amp;quot;(b ⋅ b) ⋅ (a ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ (a ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: assms)&lt;br /&gt;
    then have &amp;quot;a ⋅ (b ⋅ a) = b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;(a ⋅ (b ⋅ a)) ⋅ a = b ⋅ a&amp;quot; by (rule arg_cong)&lt;br /&gt;
    then have &amp;quot;(a ⋅ b) ⋅ (a ⋅ a) = b ⋅ a&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;(a ⋅ b) ⋅ 𝟭 = b ⋅ a&amp;quot; by (simp only: assms)&lt;br /&gt;
    then show &amp;quot;a ⋅ b = b ⋅ a&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_3&amp;diff=809</id>
		<title>Examen 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_3&amp;diff=809"/>
		<updated>2019-07-08T10:33:31Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;text ‹Examen de Lógica Matemática y Fundamentos (5 julio 2019)›&lt;br /&gt;
&lt;br /&gt;
theory examen_3_05_jul_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹Nota: En las demostraciones se pueden las reglas básicas de &lt;br /&gt;
  deducción natural de la lógica proposicional, de los cuantificadores &lt;br /&gt;
  y de la igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. ›&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     p ∨ (q ⟶ ¬(p ⟷ q))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa. *)&lt;br /&gt;
lemma &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
    have &amp;quot;q ⟶ ¬(p ⟷ q)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;q&amp;quot;&lt;br /&gt;
      show &amp;quot;¬(p ⟷ q)&amp;quot;&lt;br /&gt;
      proof&lt;br /&gt;
        assume &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
        then have &amp;quot;p&amp;quot; using `q` by (rule iffD2)&lt;br /&gt;
        with `¬p` show False by (rule notE)&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
    then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot; by (rule disjI2)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;p&amp;quot;&lt;br /&gt;
    then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot; by (rule disjI1)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa. *)&lt;br /&gt;
lemma &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
  apply (case_tac &amp;quot;p&amp;quot;)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (rule disjI2) &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule iffD2)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Se puede formalizar la teoría de las tallas&lt;br /&gt;
  usando los siguientes símbolos&lt;br /&gt;
     P x       representa que x es de la talla pequeña&lt;br /&gt;
     M x       representa que x es de la talla mediana&lt;br /&gt;
     G x       representa que x es de la talla grande&lt;br /&gt;
     Mayor x y representa que la talla de x es mayor que la de y.&lt;br /&gt;
&lt;br /&gt;
  Los axiomas de las tallas son&lt;br /&gt;
     ∃x. P x&lt;br /&gt;
     ∃x. M x&lt;br /&gt;
     ∃x. G x&lt;br /&gt;
     ∀x y. G x ∧ M y ⟶ Mayor x y&lt;br /&gt;
     ∀x y. M x ∧ P y ⟶ Mayor x y&lt;br /&gt;
     ∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z&lt;br /&gt;
     ∀x. ¬(Mayor x x)&lt;br /&gt;
 &lt;br /&gt;
  Demostrar detalladamente que la fórmula&lt;br /&gt;
      ∀x. ¬(P x) ∨ ¬(M x)&lt;br /&gt;
  es consecuencia de los axiomas de las tallas.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. M x&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. G x&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y. G x ∧ M y ⟶ Mayor x y&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y. M x ∧ P y ⟶ Mayor x y&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ¬(Mayor x x)&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. ¬(P x) ∨ ¬(M x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;¬(P a) ∨ P a&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;¬(P a) ∨ ¬(M a)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    then show &amp;quot;¬(P a) ∨ ¬(M a)&amp;quot; by (rule disjI1)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    have &amp;quot;~(M a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;M a&amp;quot;&lt;br /&gt;
      have &amp;quot;~(Mayor a a)&amp;quot; using assms(7) by (rule allE)&lt;br /&gt;
      moreover&lt;br /&gt;
      have &amp;quot;Mayor a a&amp;quot;&lt;br /&gt;
      proof -&lt;br /&gt;
        have &amp;quot;∀y. M a ∧ P y ⟶ Mayor a y&amp;quot; using assms(5) by (rule allE)&lt;br /&gt;
        then have &amp;quot;M a ∧ P a ⟶ Mayor a a&amp;quot;  by (rule allE)&lt;br /&gt;
        moreover&lt;br /&gt;
        have &amp;quot;M a ∧ P a&amp;quot; using `M a` `P a` by (rule conjI)&lt;br /&gt;
        ultimately show &amp;quot;Mayor a a&amp;quot;  by (rule mp)&lt;br /&gt;
      qed  &lt;br /&gt;
      ultimately show False by (rule notE) &lt;br /&gt;
    qed&lt;br /&gt;
    then show &amp;quot;¬ P a ∨ ¬ M a&amp;quot; by (rule disjI2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦∃x. P x;&lt;br /&gt;
        ∃x. M x;&lt;br /&gt;
        ∃x. G x;&lt;br /&gt;
        ∀x y. M x ∧ P y ⟶ Mayor x y;&lt;br /&gt;
        ∀x y. G x ∧ M y ⟶ Mayor x y;&lt;br /&gt;
        ∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z;&lt;br /&gt;
        ∀x. ¬(Mayor x x)⟧⟹&lt;br /&gt;
                             ∀x. ¬(P x) ∨ ¬(M x)&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (case_tac &amp;quot;P x&amp;quot;)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (rule disjI1, assumption)&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply (rule conjI, assumption+)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  &lt;br /&gt;
                       | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Se define las funciones&lt;br /&gt;
    fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
    | &amp;quot;nHojas (N x i d) = nHojas i + nHojas d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    fun nHojasAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojasAaux H         n = n + 1&amp;quot;&lt;br /&gt;
    | &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    definition nHojasA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojasA a ≡ nHojasAaux a 0&amp;quot;&lt;br /&gt;
  tales que&lt;br /&gt;
  + (nHojas a) es el número de hojas del árbol a. Por ejemplo, &lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
  + (nHojasAA a) es el número de hojas del árbol a, calculado &lt;br /&gt;
    con la función auxiliar nHojasAaux que usa un acumulador. Por &lt;br /&gt;
    ejemplo, &lt;br /&gt;
       nHojasA (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
 &lt;br /&gt;
  Demostrar estructuradamente (es decir, mediante una demostración &lt;br /&gt;
  declarativa) que las funciones nHojas y nHojasA son equivalentes; &lt;br /&gt;
  es decir,&lt;br /&gt;
     nHojasA a = nHojas a&lt;br /&gt;
&lt;br /&gt;
  Notas: &lt;br /&gt;
  1. Los únicos métodos que se pueden usar son induct, (simp only: ...)&lt;br /&gt;
     y this.&lt;br /&gt;
  2. En las demostraciones por introducción del cuantificador universal&lt;br /&gt;
     hay que explicitar el tipo de las variables introducidas con fix.&lt;br /&gt;
     Por ejemplo, en lugar de   &lt;br /&gt;
          fix x t n&lt;br /&gt;
     hay que escribir&lt;br /&gt;
          fix x :: &amp;#039;a and t :: &amp;quot;&amp;#039;a arbol&amp;quot; and and n :: nat&lt;br /&gt;
  -------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  &lt;br /&gt;
                  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = nHojas i + nHojas d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojasAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojasAaux H         n = n + 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition nHojasA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojasA a ≡ nHojasAaux a 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;nHojas (N e (N c H H) (N g H H)) = 4&amp;quot;&lt;br /&gt;
value &amp;quot;nHojasA (N e (N c H H) (N g H H)) = 4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma nHojasA:&lt;br /&gt;
  &amp;quot;nHojasAaux a n = (nHojas a) + n&amp;quot;&lt;br /&gt;
proof (induct a arbitrary: n)&lt;br /&gt;
  fix n&lt;br /&gt;
  have &amp;quot;nHojasAaux H n = n + 1&amp;quot; by (simp only: nHojasAaux.simps(1))&lt;br /&gt;
  also have &amp;quot;… = nHojas H + n&amp;quot; by (simp only: nHojas.simps(1))&lt;br /&gt;
  finally show &amp;quot;nHojasAaux H n = nHojas H + n&amp;quot; by this&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;a and &lt;br /&gt;
      i :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      d :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      n :: nat&lt;br /&gt;
  assume HI1: &amp;quot;⋀n. nHojasAaux i n = nHojas i + n&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;⋀n. nHojasAaux d n = nHojas d + n&amp;quot;&lt;br /&gt;
  have &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot; &lt;br /&gt;
    by (simp only: nHojasAaux.simps(2))&lt;br /&gt;
  also have &amp;quot;… = nHojasAaux i (nHojas d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI2)&lt;br /&gt;
  also have &amp;quot;… = nHojas i + (nHojas d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI1)&lt;br /&gt;
  also have &amp;quot;… = nHojas (N x i d) + n&amp;quot; &lt;br /&gt;
    by (simp only: nHojas.simps(2))&lt;br /&gt;
  finally show &amp;quot;nHojasAaux (N x i d) n = nHojas (N x i d) + n&amp;quot;  &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa del lema anterior *)&lt;br /&gt;
lemma &amp;quot;nHojasAaux a n = (nHojas a) + n&amp;quot;&lt;br /&gt;
  apply (induct a arbitrary: n)&lt;br /&gt;
   apply (simp only: nHojasAaux.simps(1))&lt;br /&gt;
   apply (simp only: nHojas.simps(1))&lt;br /&gt;
  apply (simp only: nHojasAaux.simps(2))&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;nHojasA a = nHojas a&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;nHojasA a = nHojasAaux a 0&amp;quot; by (simp only: nHojasA_def)&lt;br /&gt;
  also have &amp;quot;… = (nHojas a)&amp;quot; by (simp only: nHojasA)&lt;br /&gt;
  finally show &amp;quot;nHojasA a = nHojas a&amp;quot; by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Demostrar detalladamente que los grupos &lt;br /&gt;
  booleanos son conmutativos; es decir, si G un grupo tal que  &lt;br /&gt;
     x ⋅ x = 1 &lt;br /&gt;
  para todo x de G, entonces&lt;br /&gt;
     x ⋅ y = y ⋅ x &lt;br /&gt;
  para todo x, y de G.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son (simp only: ...) o &lt;br /&gt;
  rule.&lt;br /&gt;
  ------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Una demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. x ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. x ⋅ y = y ⋅ x&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a ⋅ b = b ⋅ a&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(b ⋅ a) ⋅ (b ⋅ a) = 𝟭&amp;quot; by (simp only: assms)&lt;br /&gt;
    then have &amp;quot;b ⋅ ((b ⋅ a) ⋅ (b ⋅ a)) = b ⋅ 𝟭&amp;quot; by (rule arg_cong)&lt;br /&gt;
    then have &amp;quot;b ⋅ ((b ⋅ a) ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
    then have &amp;quot;(b ⋅ b) ⋅ (a ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ (a ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: assms)&lt;br /&gt;
    then have &amp;quot;a ⋅ (b ⋅ a) = b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;(a ⋅ (b ⋅ a)) ⋅ a = b ⋅ a&amp;quot; by (rule arg_cong)&lt;br /&gt;
    then have &amp;quot;(a ⋅ b) ⋅ (a ⋅ a) = b ⋅ a&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;(a ⋅ b) ⋅ 𝟭 = b ⋅ a&amp;quot; by (simp only: assms)&lt;br /&gt;
    then show &amp;quot;a ⋅ b = b ⋅ a&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_3&amp;diff=808</id>
		<title>Examen 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_3&amp;diff=808"/>
		<updated>2019-07-08T10:31:08Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;text ‹Examen de Lógica Matemática y Fundamentos (5 julio 2019)›&lt;br /&gt;
&lt;br /&gt;
theory examen_3_05_jul_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text ‹Nota: En las demostraciones se pueden las reglas básicas de &lt;br /&gt;
  deducción natural de la lógica proposicional, de los cuantificadores &lt;br /&gt;
  y de la igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. ›&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     p ∨ (q ⟶ ¬(p ⟷ q))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa. *)&lt;br /&gt;
lemma &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
    have &amp;quot;q ⟶ ¬(p ⟷ q)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;q&amp;quot;&lt;br /&gt;
      show &amp;quot;¬(p ⟷ q)&amp;quot;&lt;br /&gt;
      proof&lt;br /&gt;
        assume &amp;quot;p ⟷ q&amp;quot;&lt;br /&gt;
        then have &amp;quot;p&amp;quot; using `q` by (rule iffD2)&lt;br /&gt;
        with `¬p` show False by (rule notE)&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
    then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot; by (rule disjI2)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;p&amp;quot;&lt;br /&gt;
    then show &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot; by (rule disjI1)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa. *)&lt;br /&gt;
lemma &amp;quot;p ∨ (q ⟶ ¬(p ⟷ q))&amp;quot;&lt;br /&gt;
  apply (case_tac &amp;quot;p&amp;quot;)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (rule disjI2) &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule iffD2)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Se puede formalizar la teoría de las tallas&lt;br /&gt;
  usando los siguientes símbolos&lt;br /&gt;
     P x       representa que x es de la talla pequeña&lt;br /&gt;
     M x       representa que x es de la talla mediana&lt;br /&gt;
     G x       representa que x es de la talla grande&lt;br /&gt;
     Mayor x y representa que la talla de x es mayor que la de y.&lt;br /&gt;
&lt;br /&gt;
  Los axiomas de las tallas son&lt;br /&gt;
     ∃x. P x&lt;br /&gt;
     ∃x. M x&lt;br /&gt;
     ∃x. G x&lt;br /&gt;
     ∀x y. G x ∧ M y ⟶ Mayor x y&lt;br /&gt;
     ∀x y. M x ∧ P y ⟶ Mayor x y&lt;br /&gt;
     ∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z&lt;br /&gt;
     ∀x. ¬(Mayor x x)&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
  Demostrar detalladamente que la fórmula&lt;br /&gt;
      ∀x. ¬(P x) ∨ ¬(M x)&lt;br /&gt;
  es consecuencia de los axiomas de las tallas.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  --------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. M x&amp;quot;&lt;br /&gt;
          &amp;quot;∃x. G x&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y. G x ∧ M y ⟶ Mayor x y&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y. M x ∧ P y ⟶ Mayor x y&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ¬(Mayor x x)&amp;quot;&lt;br /&gt;
  shows &amp;quot;∀x. ¬(P x) ∨ ¬(M x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  have &amp;quot;¬(P a) ∨ P a&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  then show &amp;quot;¬(P a) ∨ ¬(M a)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    then show &amp;quot;¬(P a) ∨ ¬(M a)&amp;quot; by (rule disjI1)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    have &amp;quot;~(M a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;M a&amp;quot;&lt;br /&gt;
      have &amp;quot;~(Mayor a a)&amp;quot; using assms(7) by (rule allE)&lt;br /&gt;
      moreover&lt;br /&gt;
      have &amp;quot;Mayor a a&amp;quot;&lt;br /&gt;
      proof -&lt;br /&gt;
        have &amp;quot;∀y. M a ∧ P y ⟶ Mayor a y&amp;quot; using assms(5) by (rule allE)&lt;br /&gt;
        then have &amp;quot;M a ∧ P a ⟶ Mayor a a&amp;quot;  by (rule allE)&lt;br /&gt;
        moreover&lt;br /&gt;
        have &amp;quot;M a ∧ P a&amp;quot; using `M a` `P a` by (rule conjI)&lt;br /&gt;
        ultimately show &amp;quot;Mayor a a&amp;quot;  by (rule mp)&lt;br /&gt;
      qed  &lt;br /&gt;
      ultimately show False by (rule notE) &lt;br /&gt;
    qed&lt;br /&gt;
    then show &amp;quot;¬ P a ∨ ¬ M a&amp;quot; by (rule disjI2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦∃x. P x;&lt;br /&gt;
        ∃x. M x;&lt;br /&gt;
        ∃x. G x;&lt;br /&gt;
        ∀x y. M x ∧ P y ⟶ Mayor x y;&lt;br /&gt;
        ∀x y. G x ∧ M y ⟶ Mayor x y;&lt;br /&gt;
        ∀x y z . Mayor x y ∧ Mayor y z ⟶ Mayor x z;&lt;br /&gt;
        ∀x. ¬(Mayor x x)⟧⟹&lt;br /&gt;
                             ∀x. ¬(P x) ∨ ¬(M x)&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (case_tac &amp;quot;P x&amp;quot;)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (rule disjI1, assumption)&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule_tac x = x in allE)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply (rule conjI, assumption+)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text ‹-----------------------------------------------------------------&lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  &lt;br /&gt;
                       | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Se define las funciones&lt;br /&gt;
    fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
    | &amp;quot;nHojas (N x i d) = nHojas i + nHojas d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    fun nHojasAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojasAaux H         n = n + 1&amp;quot;&lt;br /&gt;
    | &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    definition nHojasA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
      &amp;quot;nHojasA a ≡ nHojasAaux a 0&amp;quot;&lt;br /&gt;
  tales que&lt;br /&gt;
  + (nHojas a) es el número de hojas del árbol a. Por ejemplo, &lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
  + (nHojasAA a) es el número de hojas del árbol a, calculado &lt;br /&gt;
    con la función auxiliar nHojasAaux que usa un acumulador. Por &lt;br /&gt;
    ejemplo, &lt;br /&gt;
       nHojasA (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
 &lt;br /&gt;
  Demostrar estructuradamente (es decir, mediante una demostración &lt;br /&gt;
  declarativa) que las funciones nHojas y nHojasA son equivalentes; &lt;br /&gt;
  es decir,&lt;br /&gt;
     nHojasA a = nHojas a&lt;br /&gt;
&lt;br /&gt;
  Notas: &lt;br /&gt;
  1. Los únicos métodos que se pueden usar son induct, (simp only: ...)&lt;br /&gt;
     y this.&lt;br /&gt;
  2. En las demostraciones por introducción del cuantificador universal&lt;br /&gt;
     hay que explicitar el tipo de las variables introducidas con fix.&lt;br /&gt;
     Por ejemplo, en lugar de   &lt;br /&gt;
          fix x t n&lt;br /&gt;
     hay que escribir&lt;br /&gt;
          fix x :: &amp;#039;a and t :: &amp;quot;&amp;#039;a arbol&amp;quot; and and n :: nat&lt;br /&gt;
  -------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  &lt;br /&gt;
                  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = nHojas i + nHojas d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojasAaux :: &amp;quot;&amp;#039;a arbol ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojasAaux H         n = n + 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition nHojasA :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojasA a ≡ nHojasAaux a 0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;nHojas (N e (N c H H) (N g H H)) = 4&amp;quot;&lt;br /&gt;
value &amp;quot;nHojasA (N e (N c H H) (N g H H)) = 4&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma nHojasA:&lt;br /&gt;
  &amp;quot;nHojasAaux a n = (nHojas a) + n&amp;quot;&lt;br /&gt;
proof (induct a arbitrary: n)&lt;br /&gt;
  fix n&lt;br /&gt;
  have &amp;quot;nHojasAaux H n = n + 1&amp;quot; by (simp only: nHojasAaux.simps(1))&lt;br /&gt;
  also have &amp;quot;… = nHojas H + n&amp;quot; by (simp only: nHojas.simps(1))&lt;br /&gt;
  finally show &amp;quot;nHojasAaux H n = nHojas H + n&amp;quot; by this&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;a and &lt;br /&gt;
      i :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      d :: &amp;quot;&amp;#039;a arbol&amp;quot; and&lt;br /&gt;
      n :: nat&lt;br /&gt;
  assume HI1: &amp;quot;⋀n. nHojasAaux i n = nHojas i + n&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;⋀n. nHojasAaux d n = nHojas d + n&amp;quot;&lt;br /&gt;
  have &amp;quot;nHojasAaux (N x i d) n = nHojasAaux i (nHojasAaux d n)&amp;quot; &lt;br /&gt;
    by (simp only: nHojasAaux.simps(2))&lt;br /&gt;
  also have &amp;quot;… = nHojasAaux i (nHojas d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI2)&lt;br /&gt;
  also have &amp;quot;… = nHojas i + (nHojas d + n)&amp;quot; &lt;br /&gt;
    by (simp only: HI1)&lt;br /&gt;
  also have &amp;quot;… = nHojas (N x i d) + n&amp;quot; &lt;br /&gt;
    by (simp only: nHojas.simps(2))&lt;br /&gt;
  finally show &amp;quot;nHojasAaux (N x i d) n = nHojas (N x i d) + n&amp;quot;  &lt;br /&gt;
    by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa del lema anterior *)&lt;br /&gt;
lemma &amp;quot;nHojasAaux a n = (nHojas a) + n&amp;quot;&lt;br /&gt;
  apply (induct a arbitrary: n)&lt;br /&gt;
   apply (simp only: nHojasAaux.simps(1))&lt;br /&gt;
   apply (simp only: nHojas.simps(1))&lt;br /&gt;
  apply (simp only: nHojasAaux.simps(2))&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;nHojasA a = nHojas a&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;nHojasA a = nHojasAaux a 0&amp;quot; by (simp only: nHojasA_def)&lt;br /&gt;
  also have &amp;quot;… = (nHojas a)&amp;quot; by (simp only: nHojasA)&lt;br /&gt;
  finally show &amp;quot;nHojasA a = nHojas a&amp;quot; by this&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text ‹--------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Demostrar detalladamente que los grupos &lt;br /&gt;
  booleanos son conmutativos; es decir, si G un grupo tal que  &lt;br /&gt;
     x ⋅ x = 1 &lt;br /&gt;
  para todo x de G, entonces&lt;br /&gt;
     x ⋅ y = y ⋅ x &lt;br /&gt;
  para todo x, y de G.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son (simp only: ...) o &lt;br /&gt;
  rule.&lt;br /&gt;
  ------------------------------------------------------------------›&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Una demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. x ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. x ⋅ y = y ⋅ x&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a ⋅ b = b ⋅ a&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(b ⋅ a) ⋅ (b ⋅ a) = 𝟭&amp;quot; by (simp only: assms)&lt;br /&gt;
    then have &amp;quot;b ⋅ ((b ⋅ a) ⋅ (b ⋅ a)) = b ⋅ 𝟭&amp;quot; by (rule arg_cong)&lt;br /&gt;
    then have &amp;quot;b ⋅ ((b ⋅ a) ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
    then have &amp;quot;(b ⋅ b) ⋅ (a ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ (a ⋅ (b ⋅ a)) = b&amp;quot; by (simp only: assms)&lt;br /&gt;
    then have &amp;quot;a ⋅ (b ⋅ a) = b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;(a ⋅ (b ⋅ a)) ⋅ a = b ⋅ a&amp;quot; by (rule arg_cong)&lt;br /&gt;
    then have &amp;quot;(a ⋅ b) ⋅ (a ⋅ a) = b ⋅ a&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;(a ⋅ b) ⋅ 𝟭 = b ⋅ a&amp;quot; by (simp only: assms)&lt;br /&gt;
    then show &amp;quot;a ⋅ b = b ⋅ a&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_12&amp;diff=807</id>
		<title>Sol 12</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_12&amp;diff=807"/>
		<updated>2019-06-26T17:06:29Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* R12: Recorridos de árboles *}&lt;br /&gt;
&lt;br /&gt;
theory R12_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. Definir el tipo de datos arbol para representar los&lt;br /&gt;
  árboles binarios que tiene información en los nodos y en las hojas. &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
     a   d f   h &lt;br /&gt;
  se representa por &amp;quot;N e (N c (H a) (H d)) (N g (H f) (H h))&amp;quot;.&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H &amp;quot;&amp;#039;a&amp;quot; | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;N e (N c (H a) (H d)) (N g (H f) (H h))&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. Definir la función &lt;br /&gt;
     preOrden :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot;&lt;br /&gt;
  tal que (preOrden a) es el recorrido pre orden del árbol a. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     preOrden (N e (N c (H a) (H d)) (N g (H f) (H h)))&lt;br /&gt;
     = [e,c,a,d,g,f,h] &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun preOrden :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;preOrden (H x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;preOrden (N x i d) = x#((preOrden i)@(preOrden d))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;preOrden (N e (N c (H a) (H d)) (N g (H f) (H h)))  &lt;br /&gt;
       = [e,c,a,d,g,f,h]&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3. Definir la función &lt;br /&gt;
     postOrden :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot;&lt;br /&gt;
  tal que (postOrden a) es el recorrido post orden del árbol a. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     postOrden (N e (N c (H a) (H d)) (N g (H f) (H h)))&lt;br /&gt;
     = [e,c,a,d,g,f,h] &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun postOrden :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;postOrden (H x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;postOrden (N x i d) = (postOrden i)@(postOrden d)@[x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;postOrden (N e (N c (H a) (H d)) (N g (H f) (H h)))&lt;br /&gt;
       = [a,d,c,f,h,g,e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. Definir la función &lt;br /&gt;
     inOrden :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot;&lt;br /&gt;
  tal que (inOrden a) es el recorrido in orden del árbol a. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     inOrden (N e (N c (H a) (H d)) (N g (H f) (H h)))&lt;br /&gt;
     = [a,c,d,e,f,g,h]&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun inOrden :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inOrden (H x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;inOrden (N x i d) = (inOrden i)@[x]@(inOrden d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inOrden (N e (N c (H a) (H d)) (N g (H f) (H h))) &lt;br /&gt;
       = [a,c,d,e,f,g,h]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 5. Definir la función &lt;br /&gt;
     espejo :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a arbol&amp;quot;&lt;br /&gt;
  tal que (espejo a) es la imagen especular del árbol a. Por ejemplo, &lt;br /&gt;
     espejo (N e (N c (H a) (H d)) (N g (H f) (H h)))&lt;br /&gt;
     = N e (N g (H h) (H f)) (N c (H d) (H a))&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun espejo :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a arbol&amp;quot; where&lt;br /&gt;
  &amp;quot;espejo (H x)     = (H x)&amp;quot;&lt;br /&gt;
| &amp;quot;espejo (N x i d) = (N x (espejo d) (espejo i))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;espejo (N e (N c (H a) (H d)) (N g (H f) (H h))) &lt;br /&gt;
       = N e (N g (H h) (H f)) (N c (H d) (H a))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 6. Demostrar que&lt;br /&gt;
     preOrden (espejo a) = rev (postOrden a)&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma  &amp;quot;preOrden (espejo a) = rev (postOrden a)&amp;quot;&lt;br /&gt;
by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración: sin patrones *) &lt;br /&gt;
lemma &amp;quot;preOrden (espejo a) = rev (postOrden a)&amp;quot; &lt;br /&gt;
proof (induct a) &lt;br /&gt;
  fix x :: &amp;#039;a&lt;br /&gt;
  show &amp;quot;preOrden (espejo (H x)) = rev (postOrden (H x))&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;a and i d :: &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  assume HI1: &amp;quot;preOrden (espejo i) = rev (postOrden i)&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;preOrden (espejo d) = rev (postOrden d)&amp;quot;&lt;br /&gt;
  show &amp;quot;preOrden (espejo (N x i d)) = rev (postOrden (N x i d))&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;preOrden (espejo (N x i d)) = &lt;br /&gt;
          preOrden (N x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = [x] @ preOrden (espejo d) @ preOrden (espejo i)&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = rev [x] @ rev (postOrden d) @ rev (postOrden i)&amp;quot; &lt;br /&gt;
      using HI1 HI2 by simp &lt;br /&gt;
    also have &amp;quot;… = rev ((postOrden i) @ (postOrden d) @ [x])&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración: con patrones *) &lt;br /&gt;
lemma &amp;quot;preOrden (espejo a) = rev (postOrden a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a) &lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;preOrden (espejo (N x i d)) = &lt;br /&gt;
          preOrden (N x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = [x] @ preOrden (espejo d) @ preOrden (espejo i)&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = rev [x] @ rev (postOrden d) @ rev (postOrden i)&amp;quot; &lt;br /&gt;
      using HI1 HI2 by simp &lt;br /&gt;
    also have &amp;quot;… = rev ((postOrden i) @ (postOrden d) @ [x])&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 7. Demostrar que&lt;br /&gt;
     postOrden (espejo a) = rev (preOrden a)&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;postOrden (espejo a) = rev (preOrden a)&amp;quot;&lt;br /&gt;
by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;postOrden (espejo a) = rev (preOrden a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;postOrden (espejo (N x i d)) = &lt;br /&gt;
          postOrden (N x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = postOrden (espejo d) @ postOrden (espejo i) @ [x]&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;... = rev (preOrden d) @ rev (preOrden i) @ rev [x]&amp;quot; &lt;br /&gt;
      using HI1 HI2 by simp&lt;br /&gt;
    also have &amp;quot;... = rev ([x] @ preOrden i @ preOrden d)&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis  by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 8. Demostrar que&lt;br /&gt;
     inOrden (espejo a) = rev (inOrden a)&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inOrden (espejo a) = rev (inOrden a)&amp;quot;&lt;br /&gt;
by (induct a) simp_all&lt;br /&gt;
 &lt;br /&gt;
lemma &amp;quot;inOrden (espejo a) = rev (inOrden a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;inOrden (espejo (N x i d)) = &lt;br /&gt;
          inOrden (N x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = inOrden (espejo d) @ [x] @ inOrden (espejo i)&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;... = rev (inOrden d) @ rev [x] @ rev (inOrden i)&amp;quot; &lt;br /&gt;
      using HI1 HI2 by simp&lt;br /&gt;
    also have &amp;quot;... = rev (inOrden i @ [x] @ inOrden d)&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 9. Definir la función &lt;br /&gt;
     raiz :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a&amp;quot;&lt;br /&gt;
  tal que (raiz a) es la raiz del árbol a. Por ejemplo, &lt;br /&gt;
     raiz (N e (N c (H a) (H d)) (N g (H f) (H h))) = e&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun raiz :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;raiz (H x)     = x&amp;quot;&lt;br /&gt;
| &amp;quot;raiz (N x i d) = x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;raiz (N e (N c (H a) (H d)) (N g (H f) (H h))) = e&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 10. Definir la función &lt;br /&gt;
     extremo_izquierda :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a&amp;quot;&lt;br /&gt;
  tal que (extremo_izquierda a) es el nodo más a la izquierda del árbol&lt;br /&gt;
  a. Por ejemplo,  &lt;br /&gt;
     extremo_izquierda (N e (N c (H a) (H d)) (N g (H f) (H h))) = a&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun extremo_izquierda :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;extremo_izquierda (H a)      = a&amp;quot;&lt;br /&gt;
| &amp;quot;extremo_izquierda (N f x y) = (extremo_izquierda x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;extremo_izquierda (N e (N c (H a) (H d)) (N g (H f) (H h))) = a&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 11. Definir la función &lt;br /&gt;
     extremo_derecha :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a&amp;quot;&lt;br /&gt;
  tal que (extremo_derecha a) es el nodo más a la derecha del árbol&lt;br /&gt;
  a. Por ejemplo,  &lt;br /&gt;
     extremo_derecha (N e (N c (H a) (H d)) (N g (H f) (H h))) = h&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun extremo_derecha :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;extremo_derecha (H x)     = x&amp;quot;&lt;br /&gt;
| &amp;quot;extremo_derecha (N x i d) = (extremo_derecha d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;extremo_derecha (N e (N c (H a) (H d)) (N g (H f) (H h))) = h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 12. Demostrar o refutar&lt;br /&gt;
     last (inOrden a) = extremo_derecha a&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma inOrdenNoVacio: &amp;quot;inOrden a ≠ []&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
   done &lt;br /&gt;
    &lt;br /&gt;
theorem ultimoInOrden: &lt;br /&gt;
  &amp;quot;last (inOrden a) = extremo_derecha a&amp;quot;    &lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply (simp add: inOrdenNoVacio)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
theorem &amp;quot;last (inOrden a) = extremo_derecha a&amp;quot;&lt;br /&gt;
  by (induct a) (simp_all add: inOrdenNoVacio)&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;last (inOrden a) = extremo_derecha a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;last (inOrden (N x i d)) = last ((inOrden i)@[x]@(inOrden d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;... = last (inOrden d)&amp;quot; by (simp add: inOrdenNoVacio)&lt;br /&gt;
    also have &amp;quot;... = extremo_derecha d&amp;quot; using HI2 by simp&lt;br /&gt;
    also have &amp;quot;... = extremo_derecha (N x i d)&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 13. Demostrar o refutar&lt;br /&gt;
     hd (inOrden a) = extremo_izquierda a&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (inOrden a) = extremo_izquierda a&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
   apply simp&lt;br /&gt;
  apply (simp add: inOrdenNoVacio)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (inOrden a) = extremo_izquierda a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a) &lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;hd (inOrden (N x i d)) = hd((inOrden i)@[x]@(inOrden d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;... = hd (inOrden i)&amp;quot; by (simp add: inOrdenNoVacio)&lt;br /&gt;
    also have &amp;quot;... = extremo_izquierda i&amp;quot; using HI1 by simp&lt;br /&gt;
    also have &amp;quot;... = extremo_izquierda (N x i d)&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 14. Demostrar o refutar&lt;br /&gt;
     hd (preOrden a) = last (postOrden a)&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (preOrden a) = last (postOrden a)&amp;quot;&lt;br /&gt;
by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (preOrden a) = last (postOrden a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;hd (preOrden (N x i d)) = hd (x#((preOrden i)@(preOrden d)))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;... = x&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = last ((postOrden i)@(postOrden d)@[x])&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = last (postOrden (N x i d))&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 15. Demostrar o refutar&lt;br /&gt;
     hd (preOrden a) = raiz a&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (preOrden a) = raiz a&amp;quot;&lt;br /&gt;
by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (preOrden a) = raiz a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;hd (preOrden (N x i d)) = hd (x#((preOrden i)@(preOrden d)))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;... = x&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = raiz (N x i d)&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 16. Demostrar o refutar&lt;br /&gt;
     hd (inOrden a) = raiz a&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
theorem &amp;quot;hd (inOrden a) = raiz a&amp;quot;&lt;br /&gt;
quickcheck&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Quickcheck found a counterexample:&lt;br /&gt;
  a = N a1 (H a2) (H a1)&lt;br /&gt;
  &lt;br /&gt;
  Evaluated terms:&lt;br /&gt;
  hd (inOrden a) = a2&lt;br /&gt;
  raiz a = a1&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 17. Demostrar o refutar&lt;br /&gt;
     last (postOrden a) = raiz a&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;last (postOrden a) = raiz a&amp;quot;&lt;br /&gt;
by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;last (postOrden a) = raiz a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (H x)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;last (postOrden (N x i d)) = &lt;br /&gt;
          last ((postOrden i)@(postOrden d)@[x])&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = last [x]&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = x&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;... = raiz (N x i d)&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=791</id>
		<title>Examen 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=791"/>
		<updated>2019-06-26T15:08:46Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Examen de Lógica Matemática y Fundamentos (6 junio 2019) *}&lt;br /&gt;
&lt;br /&gt;
theory examen_2_06_jun_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Apellidos:&lt;br /&gt;
  Nombre: &lt;br /&gt;
*} &lt;br /&gt;
&lt;br /&gt;
text {* Sustituye la palabra uvus por tu usuario de la Universidad de&lt;br /&gt;
  Sevilla y graba el fichero con dicho usuario .thy&lt;br /&gt;
*} &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota: En las demostraciones se pueden  las reglas básicas de deducción&lt;br /&gt;
  natural de la lógica proposicional, de los cuantificadores y de la&lt;br /&gt;
  igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. &lt;br /&gt;
  *}&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     (p ⟶ q) ⟶((¬p ⟶ q) ⟶ q)&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;  &lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬p ⟶ q) ⟶ q&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;¬p ⟶ q&amp;quot;&lt;br /&gt;
    have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
    then show &amp;quot;q&amp;quot;&lt;br /&gt;
    proof (rule disjE)&lt;br /&gt;
      assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      with `¬p ⟶ q` show q by (rule mp)&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;p&amp;quot;&lt;br /&gt;
      with `p ⟶ q` show q by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Una demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; ¬ p ∨ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
     (* 1. ⟦p ⟶ q; ¬ p ⟶ q; ¬ p⟧ ⟹ q&lt;br /&gt;
        2. ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
   apply (erule_tac P=&amp;quot;¬p&amp;quot; in mp)&lt;br /&gt;
     (* 1. ⟦p ⟶ q; ¬ p⟧ ⟹ ¬ p&lt;br /&gt;
        2. ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
     (* ⟦¬ p ⟶ q; p⟧ ⟹ p *)&lt;br /&gt;
  apply assumption&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Otra demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (drule_tac G=q in mt)&lt;br /&gt;
     (* 1. ⟦¬ p ⟶ q; ¬ q⟧ ⟹ ¬ q&lt;br /&gt;
        2. ⟦¬ p ⟶ q; ¬ q; ¬ p⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
     (* ⟦¬ p ⟶ q; ¬ q; ¬ p⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
     (* ⟦¬ p ⟶ q; ¬ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
     (* ¬ p ⟹ ¬ p *)&lt;br /&gt;
  apply assumption&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Demostrar detalladamente que si R es una&lt;br /&gt;
  relación irreflexiva y transitiva, entonces R es antisimétrica. &lt;br /&gt;
  { ∀x. ¬R(x,x), &lt;br /&gt;
    ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z)) } &lt;br /&gt;
  ⊢  ∀x. ∀y. (R(x,y) ⟶ ¬R(y,x))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. ¬R(x,x)&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;∀y. (R(a,y) ⟶ ¬R(y,a))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
   fix b&lt;br /&gt;
   show &amp;quot;R(a,b) ⟶ ¬R(b,a)&amp;quot;&lt;br /&gt;
   proof&lt;br /&gt;
     assume &amp;quot;R(a,b)&amp;quot;&lt;br /&gt;
     show &amp;quot;¬ R(b,a)&amp;quot;&lt;br /&gt;
     proof&lt;br /&gt;
       assume &amp;quot;R(b,a)&amp;quot;&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b)&amp;quot; using `R(a,b)` by (rule conjI)&lt;br /&gt;
       have &amp;quot;∀y. ∀z.(R(b,y) ∧ R(y,z) ⟶ R(b,z))&amp;quot; &lt;br /&gt;
         using assms(2) by (rule allE)&lt;br /&gt;
       then have &amp;quot;∀z.(R(b,a) ∧ R(a,z) ⟶ R(b,z))&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b) ⟶ R(b,b)&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,b)&amp;quot; using `R(b,a) ∧ R(a,b)` by (rule mp)&lt;br /&gt;
       have &amp;quot;¬R(b,b)&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
       then show False using `R(b,b)` by (rule notE)&lt;br /&gt;
     qed&lt;br /&gt;
   qed&lt;br /&gt;
 qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;⟦ ∀x. ¬R(x,x);&lt;br /&gt;
     ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))⟧&lt;br /&gt;
   ⟹ ∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;   &lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ R (x, y) ⟶ ¬ R (y, x)*)&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y)⟧&lt;br /&gt;
               ⟹ ¬ R (y, x) *)&lt;br /&gt;
    apply (rule notI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x)⟧&lt;br /&gt;
           ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=y in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ R (x, x) *)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y) ∧ R (y, x)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x) *)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (y, x)&lt;br /&gt;
         3. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x)*)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
      (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Definir las funciones &lt;br /&gt;
     nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot;&lt;br /&gt;
     nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; &lt;br /&gt;
  tales que &lt;br /&gt;
  + (nNodos a) es el número de nodos de a. Por ejemplo,&lt;br /&gt;
       nNodos (N e (N c H H) (N g H H)) = 3&lt;br /&gt;
  + (nHojas a) es el número de hojas de a. Por ejemplo,&lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
&lt;br /&gt;
  Demostrar detalladamente que el número de hojas de un árbol es igual &lt;br /&gt;
  al número de nodos más 1.&lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son induct, &lt;br /&gt;
  (simp only: ...) o this.&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodos H         = 0&amp;quot;&lt;br /&gt;
| &amp;quot;nNodos (N x i d) = 1 + (nNodos i) + (nNodos d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma &amp;quot;nHojas a = (nNodos a) + 1&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  show &amp;quot;?P H&amp;quot; by (simp only: nHojas.simps(1) nNodos.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x :: &amp;#039;a and &lt;br /&gt;
      i :: &amp;quot;&amp;#039;a arbol&amp;quot; and  &lt;br /&gt;
      d :: &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
   assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot; &lt;br /&gt;
      by (simp only: nHojas.simps(2))&lt;br /&gt;
    also have &amp;quot;... = (nNodos i + 1) + (nNodos d + 1)&amp;quot; &lt;br /&gt;
      by (simp only: HI1 HI2)&lt;br /&gt;
    also have &amp;quot;... = (nNodos (N x i d)) + 1&amp;quot; &lt;br /&gt;
      by (simp only: nNodos.simps(2))&lt;br /&gt;
    finally show &amp;quot;?P (N x i d)&amp;quot; by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;nHojas a = (nNodos a) + 1&amp;quot;  &lt;br /&gt;
  apply (induct a)&lt;br /&gt;
     (* 1. nHojas H = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                          nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
   apply (simp only: nHojas.simps(1)) &lt;br /&gt;
     (* 1. 1 = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(1))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1;&lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nNodos a1 + 1 + (nNodos a2 + 1) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(2))&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Sea G un grupo. Domostrar detalladamente que &lt;br /&gt;
  para todo par de elementos x e y de G, si x es el inverso de y, &lt;br /&gt;
  entonces y es el inverso de x.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Una demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    then have &amp;quot;a^ ⋅ a = a^ ⋅ b^&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;𝟭 = a^ ⋅ b^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ b = (a^ ⋅ b^) ⋅ b&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;b = (a^ ⋅ b^) ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ (b^ ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then show &amp;quot;b = a^ &amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Otra demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    show &amp;quot;b = a^&amp;quot;&lt;br /&gt;
    proof -&lt;br /&gt;
      have &amp;quot;b = 𝟭 ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
      also have &amp;quot;… = (a^ ⋅ a) ⋅ b&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ (a ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ (b^ ⋅ b)&amp;quot; using `a = b^`  by simp&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
      also have &amp;quot;… = a^&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
      finally show &amp;quot;b = a^&amp;quot; by this&lt;br /&gt;
    qed &lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma aux1:  &amp;quot;x = y ⟹ z ⋅ x = z ⋅ y &amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
lemma aux2:  &amp;quot;x = y ⟹ x ⋅ z = y ⋅ z &amp;quot; &lt;br /&gt;
  by simp  &lt;br /&gt;
&lt;br /&gt;
lemma aux3: &amp;quot;x = y^ ⟶ y = x^&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
     (* x = y^ ⟹ y = x^ *)&lt;br /&gt;
  apply (drule aux1[where ?z = &amp;quot;x^&amp;quot;])&lt;br /&gt;
     (* x^ ⋅ x = x^ ⋅ y^ ⟹ y = x^ *)&lt;br /&gt;
  apply (simp only: inverso_i)&lt;br /&gt;
     (* 𝟭 = x^ ⋅ y^ ⟹ y = x^ *)&lt;br /&gt;
   apply (drule aux2[where ?z = &amp;quot;y&amp;quot;])&lt;br /&gt;
     (*  𝟭 ⋅ y = (x^ ⋅ y^) ⋅ y ⟹ y = x^ *)&lt;br /&gt;
   apply (simp only: neutro_i)&lt;br /&gt;
     (* y = (x^ ⋅ y^) ⋅ y ⟹ y = x^ *)&lt;br /&gt;
   apply (simp only: asociativa)&lt;br /&gt;
     (* y = x^ ⋅ (y^ ⋅ y) ⟹ y = x^ *)&lt;br /&gt;
   apply (simp only: inverso_i)&lt;br /&gt;
     (* y = x^ ⋅ 𝟭 ⟹ x^ ⋅ 𝟭 = x^ *)&lt;br /&gt;
   apply (simp only: neutro_d)&lt;br /&gt;
     (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
  apply (rule aux3)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=790</id>
		<title>Examen 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=790"/>
		<updated>2019-06-13T15:35:53Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Examen de Lógica Matemática y Fundamentos (6 junio 2019) *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota: En las demostraciones se pueden  las reglas básicas de deducción&lt;br /&gt;
  natural de la lógica proposicional, de los cuantificadores y de la&lt;br /&gt;
  igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. &lt;br /&gt;
  *}&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     (p ⟶ q) ⟶((¬p ⟶ q) ⟶ q)&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;  &lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬p ⟶ q) ⟶ q&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;¬p ⟶ q&amp;quot;&lt;br /&gt;
    have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
    then show &amp;quot;q&amp;quot;&lt;br /&gt;
    proof (rule disjE)&lt;br /&gt;
      assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      with `¬p ⟶ q` show q by (rule mp)&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;p&amp;quot;&lt;br /&gt;
      with `p ⟶ q` show q by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Una demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; ¬ p ∨ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
     (* 1. ⟦p ⟶ q; ¬ p ⟶ q; ¬ p⟧ ⟹ q&lt;br /&gt;
        2. ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
   apply (erule_tac P=&amp;quot;¬p&amp;quot; in mp)&lt;br /&gt;
     (* 1. ⟦p ⟶ q; ¬ p⟧ ⟹ ¬ p&lt;br /&gt;
        2. ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
     (* ⟦¬ p ⟶ q; p⟧ ⟹ p *)&lt;br /&gt;
  apply assumption&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Otra demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (drule_tac G=q in mt)&lt;br /&gt;
     (* 1. ⟦¬ p ⟶ q; ¬ q⟧ ⟹ ¬ q&lt;br /&gt;
        2. ⟦¬ p ⟶ q; ¬ q; ¬ p⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
     (* ⟦¬ p ⟶ q; ¬ q; ¬ p⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
     (* ⟦¬ p ⟶ q; ¬ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
     (* ¬ p ⟹ ¬ p *)&lt;br /&gt;
  apply assumption&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Demostrar detalladamente que si R es una&lt;br /&gt;
  relación irreflexiva y transitiva, entonces R es antisimétrica. &lt;br /&gt;
  { ∀x. ¬R(x,x), &lt;br /&gt;
    ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z)) } &lt;br /&gt;
  ⊢  ∀x. ∀y. (R(x,y) ⟶ ¬R(y,x))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. ¬R(x,x)&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;∀y. (R(a,y) ⟶ ¬R(y,a))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
   fix b&lt;br /&gt;
   show &amp;quot;R(a,b) ⟶ ¬R(b,a)&amp;quot;&lt;br /&gt;
   proof&lt;br /&gt;
     assume &amp;quot;R(a,b)&amp;quot;&lt;br /&gt;
     show &amp;quot;¬ R(b,a)&amp;quot;&lt;br /&gt;
     proof&lt;br /&gt;
       assume &amp;quot;R(b,a)&amp;quot;&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b)&amp;quot; using `R(a,b)` by (rule conjI)&lt;br /&gt;
       have &amp;quot;∀y. ∀z.(R(b,y) ∧ R(y,z) ⟶ R(b,z))&amp;quot; &lt;br /&gt;
         using assms(2) by (rule allE)&lt;br /&gt;
       then have &amp;quot;∀z.(R(b,a) ∧ R(a,z) ⟶ R(b,z))&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b) ⟶ R(b,b)&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,b)&amp;quot; using `R(b,a) ∧ R(a,b)` by (rule mp)&lt;br /&gt;
       have &amp;quot;¬R(b,b)&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
       then show False using `R(b,b)` by (rule notE)&lt;br /&gt;
     qed&lt;br /&gt;
   qed&lt;br /&gt;
 qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;⟦ ∀x. ¬R(x,x);&lt;br /&gt;
     ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))⟧&lt;br /&gt;
   ⟹ ∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;   &lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ R (x, y) ⟶ ¬ R (y, x)*)&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y)⟧&lt;br /&gt;
               ⟹ ¬ R (y, x) *)&lt;br /&gt;
    apply (rule notI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x)⟧&lt;br /&gt;
           ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=y in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ R (x, x) *)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y) ∧ R (y, x)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x) *)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (y, x)&lt;br /&gt;
         3. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x)*)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
      (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Definir las funciones &lt;br /&gt;
     nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot;&lt;br /&gt;
     nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; &lt;br /&gt;
  tales que &lt;br /&gt;
  + (nNodos a) es el número de nodos de a. Por ejemplo,&lt;br /&gt;
       nNodos (N e (N c H H) (N g H H)) = 3&lt;br /&gt;
  + (nHojas a) es el número de hojas de a. Por ejemplo,&lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
&lt;br /&gt;
  Demostrar detalladamente que el número de hojas de un árbol es igual &lt;br /&gt;
  al número de nodos más 1.&lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son induct, &lt;br /&gt;
  (simp only: ...) o this.&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodos H         = 0&amp;quot;&lt;br /&gt;
| &amp;quot;nNodos (N x i d) = 1 + (nNodos i) + (nNodos d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma &amp;quot;nHojas a = (nNodos a) + 1&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  show &amp;quot;?P H&amp;quot; by (simp only: nHojas.simps(1) nNodos.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot; &lt;br /&gt;
      by (simp only: nHojas.simps(2))&lt;br /&gt;
    also have &amp;quot;... = (nNodos i + 1) + (nNodos d + 1)&amp;quot; &lt;br /&gt;
      by (simp only: HI1 HI2)&lt;br /&gt;
    also have &amp;quot;... = (nNodos (N x i d)) + 1&amp;quot; &lt;br /&gt;
      by (simp only: nNodos.simps(2))&lt;br /&gt;
    finally show &amp;quot;?P (N x i d)&amp;quot; by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;nHojas a = (nNodos a) + 1&amp;quot;  &lt;br /&gt;
  apply (induct a)&lt;br /&gt;
     (* 1. nHojas H = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                          nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
   apply (simp only: nHojas.simps(1)) &lt;br /&gt;
     (* 1. 1 = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(1))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1;&lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nNodos a1 + 1 + (nNodos a2 + 1) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(2))&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Sea G un grupo. Domostrar detalladamente que &lt;br /&gt;
  para todo par de elementos x e y de G, si x es el inverso de y, &lt;br /&gt;
  entonces y es el inverso de x.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Una demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    then have &amp;quot;a^ ⋅ a = a^ ⋅ b^&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;𝟭 = a^ ⋅ b^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ b = (a^ ⋅ b^) ⋅ b&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;b = (a^ ⋅ b^) ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ (b^ ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then show &amp;quot;b = a^ &amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Otra demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    show &amp;quot;b = a^&amp;quot;&lt;br /&gt;
    proof -&lt;br /&gt;
      have &amp;quot;b = 𝟭 ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
      also have &amp;quot;… = (a^ ⋅ a) ⋅ b&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ (a ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ (b^ ⋅ b)&amp;quot; using `a = b^`  by simp&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
      also have &amp;quot;… = a^&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
      finally show &amp;quot;b = a^&amp;quot; by this&lt;br /&gt;
    qed &lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma aux1:  &amp;quot;x = y ⟹ z ⋅ x = z ⋅ y &amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
lemma aux2:  &amp;quot;x = y ⟹ x ⋅ z = y ⋅ z &amp;quot; &lt;br /&gt;
  by simp  &lt;br /&gt;
&lt;br /&gt;
lemma aux3: &amp;quot;x = y^ ⟶ y = x^&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
     (* x = y^ ⟹ y = x^ *)&lt;br /&gt;
  apply (drule aux1[where ?z = &amp;quot;x^&amp;quot;])&lt;br /&gt;
     (* x^ ⋅ x = x^ ⋅ y^ ⟹ y = x^ *)&lt;br /&gt;
  apply (simp only: inverso_i)&lt;br /&gt;
     (* 𝟭 = x^ ⋅ y^ ⟹ y = x^ *)&lt;br /&gt;
   apply (drule aux2[where ?z = &amp;quot;y&amp;quot;])&lt;br /&gt;
     (*  𝟭 ⋅ y = (x^ ⋅ y^) ⋅ y ⟹ y = x^ *)&lt;br /&gt;
   apply (simp only: neutro_i)&lt;br /&gt;
     (* y = (x^ ⋅ y^) ⋅ y ⟹ y = x^ *)&lt;br /&gt;
   apply (simp only: asociativa)&lt;br /&gt;
     (* y = x^ ⋅ (y^ ⋅ y) ⟹ y = x^ *)&lt;br /&gt;
   apply (simp only: inverso_i)&lt;br /&gt;
     (* y = x^ ⋅ 𝟭 ⟹ x^ ⋅ 𝟭 = x^ *)&lt;br /&gt;
   apply (simp only: neutro_d)&lt;br /&gt;
     (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
  apply (rule aux3)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=789</id>
		<title>Examen 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=789"/>
		<updated>2019-06-12T17:42:22Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Examen de Lógica Matemática y Fundamentos (6 junio 2019) *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota: En las demostraciones se pueden  las reglas básicas de deducción&lt;br /&gt;
  natural de la lógica proposicional, de los cuantificadores y de la&lt;br /&gt;
  igualdad:  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middle: (¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allE:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allI:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ c = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
&lt;br /&gt;
  También se pueden usar las reglas notnotI y mt que demostramos a&lt;br /&gt;
  continuación. &lt;br /&gt;
  *}&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     (p ⟶ q) ⟶((¬p ⟶ q) ⟶ q)&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;  &lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬p ⟶ q) ⟶ q&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;¬p ⟶ q&amp;quot;&lt;br /&gt;
    have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
    then show &amp;quot;q&amp;quot;&lt;br /&gt;
    proof (rule disjE)&lt;br /&gt;
      assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      with `¬p ⟶ q` show q by (rule mp)&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;p&amp;quot;&lt;br /&gt;
      with `p ⟶ q` show q by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Una demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; ¬ p ∨ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
     (* 1. ⟦p ⟶ q; ¬ p ⟶ q; ¬ p⟧ ⟹ q&lt;br /&gt;
        2. ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
   apply (erule_tac P=&amp;quot;¬p&amp;quot; in mp)&lt;br /&gt;
     (* 1. ⟦p ⟶ q; ¬ p⟧ ⟹ ¬ p&lt;br /&gt;
        2. ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
     (* ⟦¬ p ⟶ q; p⟧ ⟹ p *)&lt;br /&gt;
  apply assumption&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Otra demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;&lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
     (* ⟦p ⟶ q; ¬ p ⟶ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (drule_tac G=q in mt)&lt;br /&gt;
     (* 1. ⟦¬ p ⟶ q; ¬ q⟧ ⟹ ¬ q&lt;br /&gt;
        2. ⟦¬ p ⟶ q; ¬ q; ¬ p⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
     (* ⟦¬ p ⟶ q; ¬ q; ¬ p⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
     (* ⟦¬ p ⟶ q; ¬ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
     (* ¬ p ⟹ ¬ p *)&lt;br /&gt;
  apply assumption&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Demostrar detalladamente que si R es una&lt;br /&gt;
  relación irreflexiva y transitiva, entonces R es antisimétrica. &lt;br /&gt;
  { ∀x. ¬R(x,x), &lt;br /&gt;
    ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z)) } &lt;br /&gt;
  ⊢  ∀x. ∀y. (R(x,y) ⟶ ¬R(y,x))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. ¬R(x,x)&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;∀y. (R(a,y) ⟶ ¬R(y,a))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
   fix b&lt;br /&gt;
   show &amp;quot;R(a,b) ⟶ ¬R(b,a)&amp;quot;&lt;br /&gt;
   proof&lt;br /&gt;
     assume &amp;quot;R(a,b)&amp;quot;&lt;br /&gt;
     show &amp;quot;¬ R(b,a)&amp;quot;&lt;br /&gt;
     proof&lt;br /&gt;
       assume &amp;quot;R(b,a)&amp;quot;&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b)&amp;quot; using `R(a,b)` by (rule conjI)&lt;br /&gt;
       have &amp;quot;∀y. ∀z.(R(b,y) ∧ R(y,z) ⟶ R(b,z))&amp;quot; &lt;br /&gt;
         using assms(2) by (rule allE)&lt;br /&gt;
       then have &amp;quot;∀z.(R(b,a) ∧ R(a,z) ⟶ R(b,z))&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b) ⟶ R(b,b)&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,b)&amp;quot; using `R(b,a) ∧ R(a,b)` by (rule mp)&lt;br /&gt;
       have &amp;quot;¬R(b,b)&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
       then show False using `R(b,b)` by (rule notE)&lt;br /&gt;
     qed&lt;br /&gt;
   qed&lt;br /&gt;
 qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;⟦ ∀x. ¬R(x,x);&lt;br /&gt;
     ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))⟧&lt;br /&gt;
   ⟹ ∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;   &lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ R (x, y) ⟶ ¬ R (y, x)*)&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y)⟧&lt;br /&gt;
               ⟹ ¬ R (y, x) *)&lt;br /&gt;
    apply (rule notI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x)⟧&lt;br /&gt;
           ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=y in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ R (x, x) *)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y) ∧ R (y, x)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x) *)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (y, x)&lt;br /&gt;
         3. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x)*)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
      (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Definir las funciones &lt;br /&gt;
     nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot;&lt;br /&gt;
     nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; &lt;br /&gt;
  tales que &lt;br /&gt;
  + (nNodos a) es el número de nodos de a. Por ejemplo,&lt;br /&gt;
       nNodos (N e (N c H H) (N g H H)) = 3&lt;br /&gt;
  + (nHojas a) es el número de hojas de a. Por ejemplo,&lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
&lt;br /&gt;
  Demostrar detalladamente que el número de hojas de un árbol es igual &lt;br /&gt;
  al número de nodos más 1.&lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son induct, &lt;br /&gt;
  (simp only: ...) o this.&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodos H         = 0&amp;quot;&lt;br /&gt;
| &amp;quot;nNodos (N x i d) = 1 + (nNodos i) + (nNodos d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma &amp;quot;nHojas a = (nNodos a) + 1&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  show &amp;quot;?P H&amp;quot; by (simp only: nHojas.simps(1) nNodos.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot; &lt;br /&gt;
      by (simp only: nHojas.simps(2))&lt;br /&gt;
    also have &amp;quot;... = (nNodos i + 1) + (nNodos d + 1)&amp;quot; &lt;br /&gt;
      by (simp only: HI1 HI2)&lt;br /&gt;
    also have &amp;quot;... = (nNodos (N x i d)) + 1&amp;quot; &lt;br /&gt;
      by (simp only: nNodos.simps(2))&lt;br /&gt;
    finally show &amp;quot;?P (N x i d)&amp;quot; by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;nHojas a = (nNodos a) + 1&amp;quot;  &lt;br /&gt;
  apply (induct a)&lt;br /&gt;
     (* 1. nHojas H = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                          nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
   apply (simp only: nHojas.simps(1)) &lt;br /&gt;
     (* 1. 1 = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(1))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1;&lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nNodos a1 + 1 + (nNodos a2 + 1) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(2))&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Sea G un grupo. Domostrar detalladamente que &lt;br /&gt;
  para todo par de elementos x e y de G, si x es el inverso de y, &lt;br /&gt;
  entonces y es el inverso de x.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
(* Una demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    then have &amp;quot;a^ ⋅ a = a^ ⋅ b^&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;𝟭 = a^ ⋅ b^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ b = (a^ ⋅ b^) ⋅ b&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;b = (a^ ⋅ b^) ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ (b^ ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then show &amp;quot;b = a^ &amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Otra demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    show &amp;quot;b = a^&amp;quot;&lt;br /&gt;
    proof -&lt;br /&gt;
      have &amp;quot;b = 𝟭 ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
      also have &amp;quot;… = (a^ ⋅ a) ⋅ b&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ (a ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ (b^ ⋅ b)&amp;quot; using `a = b^`  by simp&lt;br /&gt;
      also have &amp;quot;… = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
      also have &amp;quot;… = a^&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
      finally show &amp;quot;b = a^&amp;quot; by this&lt;br /&gt;
    qed &lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=788</id>
		<title>Examen 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Examen_2&amp;diff=788"/>
		<updated>2019-06-12T15:20:57Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Examen de Lógica Matemática y Fundamentos (6-junio-2919) *}&lt;br /&gt;
&lt;br /&gt;
theory examen_2_06_jun_sol&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente que la siguiente&lt;br /&gt;
  fórmula es una tautología: &lt;br /&gt;
     (p ⟶ q) ⟶((¬p ⟶ q) ⟶ q)&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej1: &lt;br /&gt;
  shows &amp;quot;(p ⟶ q) ⟶ ((¬p ⟶ q) ⟶ q)&amp;quot;  &lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;p ⟶ q&amp;quot;&lt;br /&gt;
  show &amp;quot;(¬p ⟶ q) ⟶ q&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;¬p ⟶ q&amp;quot;&lt;br /&gt;
    have &amp;quot;¬p ∨ p&amp;quot; by (rule excluded_middle)&lt;br /&gt;
    then show &amp;quot;q&amp;quot;&lt;br /&gt;
    proof (rule disjE)&lt;br /&gt;
      assume &amp;quot;¬p&amp;quot;&lt;br /&gt;
      with `¬p ⟶ q` show q by (rule mp)&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;p&amp;quot;&lt;br /&gt;
      with `p ⟶ q` show q by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. (2.5 puntos) Demostrar detalladamente que si R es una&lt;br /&gt;
  relación irreflexiva y transitiva, entonces R es antisimétrica. &lt;br /&gt;
  { ∀x. ¬R(x,x), &lt;br /&gt;
    ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z)) } &lt;br /&gt;
  ⊢  ∀x. ∀y. (R(x,y) ⟶ ¬R(y,x))&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: simp, simp_all, &lt;br /&gt;
  auto, blast, force, fast, arith o metis&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;∀x. ¬R(x,x)&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;∀y. (R(a,y) ⟶ ¬R(y,a))&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
   fix b&lt;br /&gt;
   show &amp;quot;R(a,b) ⟶ ¬R(b,a)&amp;quot;&lt;br /&gt;
   proof&lt;br /&gt;
     assume &amp;quot;R(a,b)&amp;quot;&lt;br /&gt;
     show &amp;quot;¬ R(b,a)&amp;quot;&lt;br /&gt;
     proof&lt;br /&gt;
       assume &amp;quot;R(b,a)&amp;quot;&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b)&amp;quot; using `R(a,b)` by (rule conjI)&lt;br /&gt;
       have &amp;quot;∀y. ∀z.(R(b,y) ∧ R(y,z) ⟶ R(b,z))&amp;quot; &lt;br /&gt;
         using assms(2) by (rule allE)&lt;br /&gt;
       then have &amp;quot;∀z.(R(b,a) ∧ R(a,z) ⟶ R(b,z))&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,a) ∧ R(a,b) ⟶ R(b,b)&amp;quot; by (rule allE)&lt;br /&gt;
       then have &amp;quot;R(b,b)&amp;quot; using `R(b,a) ∧ R(a,b)` by (rule mp)&lt;br /&gt;
       have &amp;quot;¬R(b,b)&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
       then show False using `R(b,b)` by (rule notE)&lt;br /&gt;
     qed&lt;br /&gt;
   qed&lt;br /&gt;
 qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;⟦ ∀x. ¬R(x,x);&lt;br /&gt;
     ∀x. ∀y. ∀z. (R(x,y) ∧ R(y,z) ⟶ R(x,z))⟧&lt;br /&gt;
   ⟹ ∀x. ∀y. (R(x,y) ⟶ ¬ R(y,x))&amp;quot;   &lt;br /&gt;
  apply (rule allI)+&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ R (x, y) ⟶ ¬ R (y, x)*)&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y)⟧&lt;br /&gt;
               ⟹ ¬ R (y, x) *)&lt;br /&gt;
    apply (rule notI)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x. ¬ R (x, x);&lt;br /&gt;
                 ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ ∀x y z. R (x, y) ∧ R (y, z) ⟶ R (x, z);&lt;br /&gt;
                 R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x)⟧&lt;br /&gt;
           ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀y z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=y in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 ∀z. R (x, y) ∧ R (y, z) ⟶ R (x, z)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x); &lt;br /&gt;
                 ¬ R (x, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* ⋀x y. ⟦ R (x, y); &lt;br /&gt;
                 R (y, x);&lt;br /&gt;
                 R (x, y) ∧ R (y, x) ⟶ R (x, x)⟧&lt;br /&gt;
               ⟹ R (x, x) *)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y) ∧ R (y, x)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x) *)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
      (* 1. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (x, y)&lt;br /&gt;
         2. ⋀x y. ⟦R (x, y); R (y, x)⟧ ⟹ R (y, x)&lt;br /&gt;
         3. ⋀x y. ⟦R (x, y); R (y, x); R (x, x)⟧ ⟹ R (x, x)*)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
      (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3 (2.5 puntos) Consideremos el árbol binario definido por&lt;br /&gt;
     datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  Por ejemplo, el árbol&lt;br /&gt;
          e&lt;br /&gt;
         / \&lt;br /&gt;
        /   \&lt;br /&gt;
       c     g&lt;br /&gt;
      / \   / \&lt;br /&gt;
             &lt;br /&gt;
  se representa por &amp;quot;N e (N c H H) (N g H H)&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Definir las funciones &lt;br /&gt;
     nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot;&lt;br /&gt;
     nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; &lt;br /&gt;
  tales que &lt;br /&gt;
  + (nNodos a) es el número de nodos de a. Por ejemplo,&lt;br /&gt;
       nNodos (N e (N c H H) (N g H H)) = 3&lt;br /&gt;
  + (nHojas a) es el número de hojas de a. Por ejemplo,&lt;br /&gt;
       nHojas (N e (N c H H) (N g H H)) = 4&lt;br /&gt;
&lt;br /&gt;
  Demostrar detalladamente que el número de hojas de un árbol es igual &lt;br /&gt;
  al número de nodos más 1.&lt;br /&gt;
&lt;br /&gt;
  Nota: Los únicos métodos que se pueden usar son induct, &lt;br /&gt;
  (simp only: ...) o this.&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = H  | N &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a arbol&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nNodos :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nNodos H         = 0&amp;quot;&lt;br /&gt;
| &amp;quot;nNodos (N x i d) = 1 + (nNodos i) + (nNodos d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun nHojas :: &amp;quot;&amp;#039;a arbol ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;nHojas H         = 1&amp;quot;&lt;br /&gt;
| &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa *)&lt;br /&gt;
lemma ej3: &lt;br /&gt;
  &amp;quot;nHojas a = (nNodos a) + 1&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  show &amp;quot;?P H&amp;quot; by (simp only: nHojas.simps(1) nNodos.simps(1)) &lt;br /&gt;
next&lt;br /&gt;
  fix x i d&lt;br /&gt;
  assume HI1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  assume HI2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (N x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;nHojas (N x i d) = (nHojas i) + (nHojas d)&amp;quot; &lt;br /&gt;
      by (simp only: nHojas.simps(2))&lt;br /&gt;
    also have &amp;quot;... = (nNodos i + 1) + (nNodos d + 1)&amp;quot; &lt;br /&gt;
      by (simp only: HI1 HI2)&lt;br /&gt;
    also have &amp;quot;... = (nNodos (N x i d)) + 1&amp;quot; &lt;br /&gt;
      by (simp only: nNodos.simps(2))&lt;br /&gt;
    finally show &amp;quot;?P (N x i d)&amp;quot; by this&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma ej3_b: &lt;br /&gt;
  &amp;quot;nHojas a = (nNodos a) + 1&amp;quot;  &lt;br /&gt;
  apply (induct a)&lt;br /&gt;
     (* 1. nHojas H = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                          nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
   apply (simp only: nHojas.simps(1)) &lt;br /&gt;
     (* 1. 1 = nNodos H + 1&lt;br /&gt;
        2. ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                        nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                      ⟹ nHojas (N x1 a1 a2) = nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(1))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1; &lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nHojas (N x1 a1 a2) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nHojas.simps(2))&lt;br /&gt;
     (* ⋀x1 a1 a2. ⟦ nHojas a1 = nNodos a1 + 1;&lt;br /&gt;
                     nHojas a2 = nNodos a2 + 1⟧&lt;br /&gt;
                   ⟹ nNodos a1 + 1 + (nNodos a2 + 1) = &lt;br /&gt;
                       nNodos (N x1 a1 a2) + 1 *)&lt;br /&gt;
  apply (simp only: nNodos.simps(2))&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. (2.5 puntos) Sea G un grupo. Domostrar detalladamente que &lt;br /&gt;
  para todo par de elementos x e y de G, si x es el inverso de y, &lt;br /&gt;
  entonces y es el inverso de x.&lt;br /&gt;
&lt;br /&gt;
  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,&lt;br /&gt;
  fast, arith o metis &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
locale grupo =&lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and neutro_d:   &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
(* Notas sobre notación:&lt;br /&gt;
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).&lt;br /&gt;
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
lemma ej5:&lt;br /&gt;
  shows &amp;quot;∀x. ∀y. x = y^ ⟶ y = x^&amp;quot; &lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;a = b^ ⟶ b = a^&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;a = b^&amp;quot;&lt;br /&gt;
    then have &amp;quot;a^ ⋅ a = a^ ⋅ b^&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;𝟭 = a^ ⋅ b^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then have &amp;quot;𝟭 ⋅ b = (a^ ⋅ b^) ⋅ b&amp;quot; by simp&lt;br /&gt;
    then have &amp;quot;b = (a^ ⋅ b^) ⋅ b&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ (b^ ⋅ b)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    then have &amp;quot;b = a^ ⋅ 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    then show &amp;quot;b = a^ &amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Ejercicios&amp;diff=787</id>
		<title>Ejercicios</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Ejercicios&amp;diff=787"/>
		<updated>2019-06-06T13:52:37Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta página se encuentran los ejercicios para resolver de manera colaborativa que complementan al [https://www.cs.us.es/~jalonso/cursos/lmf-18/ejercicios/ejercicios-LMF-2018-19.pdf libro de ejercicios].&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 1&amp;#039;&amp;#039;&amp;#039;: Sintaxis y semántica de la lógica proposicional. ([[R1 |Enunciado]] y [[Relación 1 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 2&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional. ([[R2 |Enunciado]] y [[Relación 2 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 3&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional (II). ([[R3 |Enunciado]] y [[Relación 3 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 4&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional con Isabelle ([[R4 |Enunciado]], [[Relación 4 |Solución colaborativa]] y [[Sol 4 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 5&amp;#039;&amp;#039;&amp;#039;: Sintaxis y semántica de la lógica de primer orden. ([[R5 |Enunciado]] y [[Relación 5 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 6&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R6.thy Deducción natural en lógica de primer orden con Isabelle] ([[R6 |Enunciado]], [[Relación  |Solución colaborativa]] y [[Sol 6 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 7&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R7.thy Deducción natural en lógica proposicional con Isabelle basada en tácticas] ([[R7 |Enunciado]], [[Relación 7 |Solución colaborativa]] y [[Sol 7 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 7b&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica de primer orden con Isabelle basada en tácticas. ([[Sol 7b | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 8&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R8.thy Argumentación en lógica de primer orden con Isabelle.] ([[R8 |Enunciado]], [[Relación 8 |Solución colaborativa]] y [[Sol 8 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 9&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R9.thy Programación funcional en Isabelle] ([[R9 |Enunciado]], [[Relación 9 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 10&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R10.thy Programación funcional en Isabelle (2)] ([[R10 |Enunciado]], [[Relación 10 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 11&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R11.thy Razonamiento sobre programas en Isabelle/HOL] ([[R11 |Enunciado]], [[Relación 11 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 12&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R12.thy Recorridos de árboles en Isabelle/HOL] ([[R12 |Enunciado]], [[Relación 12 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 13&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R13.thy Definiciones inductivas: clausuras] ([[R13 |Enunciado]], [[Relación 13 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 14&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R14.thy Desarrollo de teorías axiomáticas] ([[R14 |Enunciado]], [[Relación 14 |Solución colaborativa]]).&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Conjuntos,_funciones_y_relaciones&amp;diff=778</id>
		<title>Conjuntos, funciones y relaciones</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Conjuntos,_funciones_y_relaciones&amp;diff=778"/>
		<updated>2019-05-29T14:53:19Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 10: Conjuntos, funciones y relaciones *}&lt;br /&gt;
&lt;br /&gt;
theory T10_Conjuntos_funciones_y_relaciones&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section {* Conjuntos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Operaciones con conjuntos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. La teoría elemental de conjuntos es HOL/Set.thy.&lt;br /&gt;
&lt;br /&gt;
  Nota. En un conjunto todos los elemento son del mismo tipo (por&lt;br /&gt;
  ejemplo, del tipo τ) y el conjunto tiene tipo (en el ejemplo, &amp;quot;τ set&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
  Reglas de la intersección:&lt;br /&gt;
  · IntI:  ⟦c ∈ A; c ∈ B⟧ ⟹ c ∈ A ∩ B&lt;br /&gt;
  · IntD1: c ∈ A ∩ B ⟹ c ∈ A&lt;br /&gt;
  · IntD2: c ∈ A ∩ B ⟹ c ∈ B&lt;br /&gt;
&lt;br /&gt;
  Nota. Propiedades del complementario:&lt;br /&gt;
  · Compl_iff: (c ∈ - A) = (c ∉ A)&lt;br /&gt;
  · Compl_Un:  - (A ∪ B) = - A ∩ - B&lt;br /&gt;
&lt;br /&gt;
  Nota. El conjunto vacío se representa por {} y el universal por UNIV. &lt;br /&gt;
&lt;br /&gt;
  Nota. Propiedades de la diferencia y del complementario:&lt;br /&gt;
  · Diff_disjoint:   A ∩ (B - A) = {}&lt;br /&gt;
  · Compl_partition: A ∪ - A = UNIV&lt;br /&gt;
&lt;br /&gt;
  Nota. Reglas de la relación de subconjunto:&lt;br /&gt;
  · subsetI: (⋀x. x ∈ A ⟹ x ∈ B) ⟹ A ⊆ B&lt;br /&gt;
  · subsetD: ⟦A ⊆ B; c ∈ A⟧ ⟹ c ∈ B   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo: A ∪ B ⊆ C syss A ⊆ C ∧ B ⊆ C.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(A ∪ B ⊆ C) = (A ⊆ C ∧ B ⊆ C)&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo: A ⊆ -B syss B ⊆ -A.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(A ⊆ -B) = (B ⊆ -A)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Principio de extensionalidad de conjuntos:&lt;br /&gt;
  · set_eqI: (⋀x. (x ∈ A) = (x ∈ B)) ⟹ A = B&lt;br /&gt;
&lt;br /&gt;
  Reglas de la igualdad de conjuntos:&lt;br /&gt;
  · equalityI:  ⟦A ⊆ B; B ⊆ A⟧ ⟹ A = B&lt;br /&gt;
  · equalityD1: A = B ⟹ A ⊆ B&lt;br /&gt;
  · equalityD2: A = B ⟹ B ⊆ A &lt;br /&gt;
  · equalityE:  ⟦A = B; ⟦A ⊆ B; B ⊆ A⟧ ⟹ P⟧ ⟹ P   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre intersección y conjunción]&lt;br /&gt;
  &amp;quot;x ∈ A ∩ B&amp;quot; syss &amp;quot;x ∈ A&amp;quot; y &amp;quot;x ∈ B&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(x ∈ A ∩ B) = (x ∈ A ∧ x ∈ B)&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre unión y disyunción]&lt;br /&gt;
  x ∈ A ∪ B syss x ∈ A ó x ∈ B.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(x ∈ A ∪ B) = (x ∈ A ∨ x ∈ B)&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre subconjunto e implicación]&lt;br /&gt;
  A ⊆ B syss para todo x, si x ∈ A entonces x ∈ B.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(A ⊆ B) = (∀ x. x ∈ A ⟶ x ∈ B)&amp;quot; &lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre complementario y negación]&lt;br /&gt;
  x pertenece al complementario de A syss x no pertenece a A.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(x ∈ -A) = (x ∉ A)&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection {* Notación de conjuntos finitos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. La teoría de conjuntos finitos es HOL/Finite_Set.thy.&lt;br /&gt;
&lt;br /&gt;
  Nota. Los conjuntos finitos se definen por inducción a partir de las&lt;br /&gt;
  siguientes reglas inductivas:&lt;br /&gt;
  · El conjunto vacío es un conjunto finito.&lt;br /&gt;
    · emptyI: &amp;quot;finite {}&amp;quot;&lt;br /&gt;
  · Si se le añade un elemento a un conjunto finito se obtiene otro&lt;br /&gt;
    conjunto finito. &lt;br /&gt;
    · insertI: &amp;quot;finite A ⟹ finite (insert a A)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
  A continuación se muestran ejemplos de conjuntos finitos.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;insert 2 {} = {2} ∧&lt;br /&gt;
   insert 3 {2} = {2,3} ∧&lt;br /&gt;
   insert 2 {2,3} = {2,3} ∧&lt;br /&gt;
   {2,3} = {3,2,3,2,2}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. Los conjuntos finitos se representan con la notación conjuntista&lt;br /&gt;
  habitual: los elementos entre llaves y separados por comas. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo: {a,b} ∪ {c,d} = {a,b,c,d}   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{a,b} ∪ {c,d} = {a,b,c,d}&amp;quot; &lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de conjetura falsa y su refutación. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{a,b} ∩ {b,c} = {b}&amp;quot; &lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
(* Auto Quickcheck found a counterexample:&lt;br /&gt;
    a = a⇩1&lt;br /&gt;
    b = a⇩2&lt;br /&gt;
    c = a⇩1&lt;br /&gt;
   Evaluated terms:&lt;br /&gt;
    {a, b} ∩ {b, c} = {a⇩2, a⇩1}&lt;br /&gt;
    {b} = {a⇩2}&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo con la conjetura corregida.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{a,b} ∩ {b,c} = (if a = c then {a,b} else {b})&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Sumas de conjuntos finitos:&lt;br /&gt;
  · ∑A es la suma de los elementos del conjunto finito A. Por ejemplo, &lt;br /&gt;
      value &amp;quot;∑{1,2,3}::int&amp;quot; -- &amp;quot;= 6&amp;quot;&lt;br /&gt;
  · (setsum f A) es la suma de la aplicación de f a los elementos del&lt;br /&gt;
    conjunto finito A,  Por ejemplo,&lt;br /&gt;
       value &amp;quot;setsum (λx. x*x) {1,2,3}::int&amp;quot; -- &amp;quot;= 14&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplos de definiciones recursivas sobre conjuntos finitos: &lt;br /&gt;
  Sea A un conjunto finito de números naturales.&lt;br /&gt;
  · sumaConj A es la suma de los elementos A.&lt;br /&gt;
  · sumaCuadradosConj A es la suma de los cuadrados de los elementos A. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition sumaConj :: &amp;quot;nat set ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sumaConj S ≡ ∑S&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sumaConj {2,5,3}&amp;quot; ― ‹= 10›&lt;br /&gt;
value &amp;quot;∑{2::nat,5,3}&amp;quot; ― ‹= 10›&lt;br /&gt;
&lt;br /&gt;
definition sumaCuadradosConj :: &amp;quot;nat set ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sumaCuadradosConj S ≡ ∑x∈S. x*x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sumaCuadradosConj {2,5,3}&amp;quot; ― ‹= 38›&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. Para simplificar lo que sigue, declaramos las anteriores&lt;br /&gt;
  definiciones como reglas de simplificación.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
declare sumaConj_def [simp]&lt;br /&gt;
declare sumaCuadradosConj_def [simp]&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplos de evaluación de las anteriores definiciones recursivas.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;sumaConj {1,2,3,4} = 10 ∧&lt;br /&gt;
   sumaCuadradosConj {1,2,3,4} = 30&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Inducción sobre conjuntos finitos: Para demostrar que todos los&lt;br /&gt;
  conjuntos finitos tienen una propiedad P basta probar que&lt;br /&gt;
  · El conjunto vacío tiene la propiedad P.&lt;br /&gt;
  · Si a un conjunto finito que tiene la propiedad P se le añade un&lt;br /&gt;
    nuevo elemento, el conjunto obtenido sigue teniendo la propiedad P. &lt;br /&gt;
  En forma de regla&lt;br /&gt;
  · finite_induct: ⟦finite F; &lt;br /&gt;
                    P {}; &lt;br /&gt;
                    ⋀x F. ⟦finite F; x ∉ F; P F⟧ ⟹ P ({x} ∪ F)⟧ &lt;br /&gt;
                   ⟹ P F   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de inducción sobre conjuntos finitos: Sea S un conjunto finito&lt;br /&gt;
  de números naturales. Entonces todos los elementos de S son menores o&lt;br /&gt;
  iguales que la suma de los elementos de S. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;finite S ⟹ ∀x∈S. x ≤ sumaConj S&amp;quot;&lt;br /&gt;
  apply (induct rule: finite_induct)&lt;br /&gt;
     (* 1. ∀x∈{}. x ≤ sumaConj {}&lt;br /&gt;
        2. ⋀x F. ⟦finite F; x ∉ F; ∀x∈F. x ≤ sumaConj F⟧&lt;br /&gt;
                 ⟹ ∀xa∈insert x F. xa ≤ sumaConj (insert x F) *)&lt;br /&gt;
   apply simp&lt;br /&gt;
     (* 1. ⋀x F. ⟦finite F; x ∉ F; ∀x∈F. x ≤ sumaConj F⟧&lt;br /&gt;
                 ⟹ ∀xa∈insert x F. xa ≤ sumaConj (insert x F) *)&lt;br /&gt;
   apply auto&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;finite S ⟹ ∀x∈S. x ≤ sumaConj S&amp;quot;&lt;br /&gt;
  by (induct rule: finite_induct) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma sumaConj_acota: &lt;br /&gt;
  &amp;quot;finite S ⟹ ∀x∈S. x ≤ sumaConj S&amp;quot;&lt;br /&gt;
proof (induct rule: finite_induct)&lt;br /&gt;
  show &amp;quot;∀x ∈ {}. x ≤ sumaConj {}&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x and F&lt;br /&gt;
  assume fF: &amp;quot;finite F&amp;quot; &lt;br /&gt;
     and xF: &amp;quot;x ∉ F&amp;quot; &lt;br /&gt;
     and HI: &amp;quot;∀ x∈F. x ≤ sumaConj F&amp;quot;&lt;br /&gt;
  show &amp;quot;∀y ∈ insert x F. y ≤ sumaConj (insert x F)&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    fix y &lt;br /&gt;
    assume &amp;quot;y ∈ insert x F&amp;quot;&lt;br /&gt;
    show &amp;quot;y ≤ sumaConj (insert x F)&amp;quot;&lt;br /&gt;
    proof (cases &amp;quot;y = x&amp;quot;)&lt;br /&gt;
      assume &amp;quot;y = x&amp;quot;&lt;br /&gt;
      then have &amp;quot;y ≤ x + (sumaConj F)&amp;quot; by simp&lt;br /&gt;
      also have &amp;quot;… = sumaConj (insert x F)&amp;quot;  by (simp add: fF xF)&lt;br /&gt;
      finally show ?thesis .&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;y ≠ x&amp;quot;&lt;br /&gt;
      then have &amp;quot;y ∈ F&amp;quot; using `y ∈ insert x F` by simp&lt;br /&gt;
      then have &amp;quot;y ≤ sumaConj F&amp;quot; using HI by blast&lt;br /&gt;
      also have &amp;quot;… ≤ x + (sumaConj F)&amp;quot; by simp&lt;br /&gt;
      also have &amp;quot;… = sumaConj (insert x F)&amp;quot; using fF xF by simp&lt;br /&gt;
      finally show ?thesis .&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection {* Definiciones por comprensión *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El conjunto de los elementos que cumple la propiedad P se representa&lt;br /&gt;
  por {x. P}. &lt;br /&gt;
&lt;br /&gt;
  Reglas de comprensión (relación entre colección y pertenencia):&lt;br /&gt;
  · mem_Collect_eq: (a ∈ {x. P x}) = P a&lt;br /&gt;
  · Collect_mem_eq: {x. x ∈ A} = A   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de comprensión: {x. P x ∨ x ∈ A} = {x. P x} ∪ A   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{x. P x ∨ x ∈ A} = {x. P x} ∪ A&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de comprensión: {x. P x ⟶ Q x} = -{x. P x} ∪ {x. Q x}   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{x. P x ⟶ Q x} = -{x. P x} ∪ {x. Q x}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo con la sintaxis general de comprensión.   &lt;br /&gt;
     {p*q | p q. p ∈ prime ∧ q ∈ prime} = &lt;br /&gt;
     {z. ∃p q. z = p*q ∧ p ∈ prime ∧ q ∈ prime}   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;{p*q | p q. p ∈ prime ∧ q ∈ prime} = &lt;br /&gt;
   {z. ∃p q. z = p*q ∧ p ∈ prime ∧ q ∈ prime}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
   En HOL, la notación conjuntista es azúcar sintáctica:&lt;br /&gt;
   · x ∈ A  es equivalente a A(x).&lt;br /&gt;
   · {x. P} es equivalente a λx. P.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de definición por comprensión: El conjunto de los pares es el&lt;br /&gt;
  de los números n para los que existe un m tal que n = 2*m.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition Pares :: &amp;quot;nat set&amp;quot; where&lt;br /&gt;
  &amp;quot;Pares ≡ {n. ∃m. n = 2*m }&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo. Los números 2 y 34 son pares.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;2 ∈ Pares ∧&lt;br /&gt;
   34 ∈ Pares&amp;quot; &lt;br /&gt;
  by (simp add: Pares_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Definición. El conjunto de los impares es el de los números n para los&lt;br /&gt;
  que existe un m tal que n = 2*m + 1.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition Impares :: &amp;quot;nat set&amp;quot; where&lt;br /&gt;
  &amp;quot;Impares ≡ {n. ∃m. n = 2*m + 1}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo con las reglas de intersección y comprensión: El conjunto de&lt;br /&gt;
  los pares es disjunto con el de los impares. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  apply auto&lt;br /&gt;
    (* ⟦x ∈ Pares; x ∈ Impares⟧ ⟹ False *)&lt;br /&gt;
  apply (simp add: Pares_def Impares_def)&lt;br /&gt;
    (* ⟦∃m. x = 2 * m; ∃m. x = Suc (2 * m)⟧ ⟹ False *)&lt;br /&gt;
  apply presburger&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa sin auto ni presburger›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
    (* x ∈ Pares ∩ Impares ⟹ False *)&lt;br /&gt;
  apply (erule IntE)&lt;br /&gt;
    (* ⟦x ∈ Pares; x ∈ Impares⟧ ⟹ False *)&lt;br /&gt;
  apply (simp add: Pares_def Impares_def)&lt;br /&gt;
    (* ⟦∃m. x = 2 * m; ∃m. x = Suc (2 * m)⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)+&lt;br /&gt;
    (* ⋀m ma. ⟦x = 2 * m; x = Suc (2 * ma)⟧ ⟹ False *)&lt;br /&gt;
  apply (simp add: Suc_double_not_eq_double)&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  by (auto simp add: Pares_def Impares_def, presburger)&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x assume S: &amp;quot;x ∈ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  then have &amp;quot;x ∈ Pares&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;∃m. x = 2 * m&amp;quot; by (simp only: Pares_def mem_Collect_eq)&lt;br /&gt;
  then obtain p where p: &amp;quot;x = 2 * p&amp;quot; .. &lt;br /&gt;
  from S have &amp;quot;x ∈ Impares&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;∃ m. x = 2 * m + 1&amp;quot; by (simp only: Impares_def mem_Collect_eq)&lt;br /&gt;
  then obtain q where q: &amp;quot;x = 2 * q + 1&amp;quot; .. &lt;br /&gt;
  from p and q show &amp;quot;False&amp;quot; by presburger&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración declarativa sin implícitos ni presburger›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x assume S: &amp;quot;x ∈ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  then have &amp;quot;x ∈ Pares&amp;quot; by (rule IntD1)&lt;br /&gt;
  then have &amp;quot;∃m. x = 2 * m&amp;quot; by (simp only: Pares_def mem_Collect_eq)&lt;br /&gt;
  then obtain p where p: &amp;quot;x = 2 * p&amp;quot; .. &lt;br /&gt;
  from S have &amp;quot;x ∈ Impares&amp;quot; by (rule IntD2)&lt;br /&gt;
  then have &amp;quot;∃ m. x = 2 * m + 1&amp;quot; by (simp only: Impares_def mem_Collect_eq)&lt;br /&gt;
  then obtain q where q: &amp;quot;x = 2 * q + 1&amp;quot; .. &lt;br /&gt;
  from p and q show &amp;quot;False&amp;quot; by (simp add: Suc_double_not_eq_double)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection {* Cuantificadores acotados *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Reglas de cuantificador universal acotado (&amp;quot;bounded&amp;quot;):&lt;br /&gt;
  · ballI: (⋀x. x ∈ A ⟹ P x) ⟹ ∀x∈A. P x&lt;br /&gt;
  · bspec: ⟦∀x∈A. P x; x ∈ A⟧ ⟹ P x&lt;br /&gt;
&lt;br /&gt;
  Reglas de cuantificador existencial acotado (&amp;quot;bounded&amp;quot;):&lt;br /&gt;
  · bexI: ⟦P x; x ∈ A⟧ ⟹ ∃x∈A. P x&lt;br /&gt;
  · bexE: ⟦∃x∈A. P x; ⋀x. ⟦x ∈ A; P x⟧ ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  Reglas de la unión indexada:&lt;br /&gt;
  · UN_iff: (b ∈ (⋃x∈A. B x)) = (∃x∈A. b ∈ B x)&lt;br /&gt;
  · UN_I:   ⟦a ∈ A; b ∈ B a⟧ ⟹ b ∈ (⋃x∈A. B x)&lt;br /&gt;
  · UN_E:   ⟦b ∈ (⋃x∈A. B x); ⋀x. ⟦x ∈ A; b ∈ B x⟧ ⟹ R⟧ ⟹ R&lt;br /&gt;
&lt;br /&gt;
  Reglas de la unión de una familia:&lt;br /&gt;
  · Union_def: ⋃S = (⋃x∈S. x)&lt;br /&gt;
  · Union_iff: (A ∈ ⋃C) = (∃X∈C. A ∈ X)&lt;br /&gt;
&lt;br /&gt;
  Reglas de la intersección indexada:&lt;br /&gt;
  · INT_iff: (b ∈ (⋂x∈A. B x)) = (∀x∈A. b ∈ B x)&lt;br /&gt;
  · INT_I:   (⋀x. x ∈ A ⟹ b ∈ B x) ⟹ b ∈ (⋂x∈A. B x)&lt;br /&gt;
  · INT_E:   ⟦b ∈ (⋂x∈A. B x); b ∈ B a ⟹ R; a ∉ A ⟹ R⟧ ⟹ R&lt;br /&gt;
&lt;br /&gt;
  Reglas de la intersección de una familia:&lt;br /&gt;
  · Inter_def: ⋂S = (⋂x∈S. x)&lt;br /&gt;
  · Inter_iff: (A ∈ ⋂C) = (∀X∈C. A ∈ X)&lt;br /&gt;
&lt;br /&gt;
  Abreviaturas:&lt;br /&gt;
  · &amp;quot;Collect P&amp;quot; es lo mismo que &amp;quot;{x. P}&amp;quot;.&lt;br /&gt;
  · &amp;quot;All P&amp;quot;     es lo mismo que &amp;quot;∀x. P x&amp;quot;.&lt;br /&gt;
  · &amp;quot;Ex P&amp;quot;      es lo mismo que &amp;quot;∃x. P x&amp;quot;.&lt;br /&gt;
  · &amp;quot;Ball A P&amp;quot;  es lo mismo que &amp;quot;∀x∈A. P x&amp;quot;.&lt;br /&gt;
  · &amp;quot;Bex A P&amp;quot;   es lo mismo que &amp;quot;∃x∈A. P x&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Conjuntos finitos y cardinalidad *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El número de elementos de un conjunto finito A es el cardinal de A y&lt;br /&gt;
  se representa por &amp;quot;card A&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplos de cardinales de conjuntos finitos.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;card {} = 0 ∧&lt;br /&gt;
   card {4} = 1 ∧&lt;br /&gt;
   card {4,1} = 2 ∧&lt;br /&gt;
   x ≠ y ⟹ card {x,y} = 2&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Propiedades de cardinales:&lt;br /&gt;
  · Cardinal de la unión de conjuntos finitos:&lt;br /&gt;
    card_Un_Int: ⟦finite A; finite B⟧ &lt;br /&gt;
                 ⟹ card A + card B = card (A ∪ B) + card (A ∩ B)&amp;quot; &lt;br /&gt;
  · Cardinal del conjunto potencia: &lt;br /&gt;
    card_Pow: finite A ⟹ card (Pow A) = 2 ^ card A&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Funciones *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  La teoría de funciones es HOL/Fun.thy. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Nociones básicas de funciones *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Principio de extensionalidad para funciones:&lt;br /&gt;
  · ext: (⋀x. f x = g x) ⟹ f = g&lt;br /&gt;
&lt;br /&gt;
  Actualización de funciones  &lt;br /&gt;
  · fun_upd_apply: (f(x := y)) z = (if z = x then y else f z)&lt;br /&gt;
  · fun_upd_upd:   f(x := y, x := z) = f(x := z)&lt;br /&gt;
&lt;br /&gt;
  Función identidad&lt;br /&gt;
  · id_def: id ≡ λx. x&lt;br /&gt;
&lt;br /&gt;
  Composición de funciones:&lt;br /&gt;
  · o_def: f ∘ g = (λx. f (g x))&lt;br /&gt;
&lt;br /&gt;
  Asociatividad de la composición:&lt;br /&gt;
  · o_assoc: f ∘ (g ∘ h) = (f ∘ g) ∘ h&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Funciones inyectivas, suprayectivas y biyectivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Función inyectiva sobre A:&lt;br /&gt;
  · inj_on_def: inj_on f A ≡ ∀x∈A. ∀y∈A. f x = f y ⟶ x = y&lt;br /&gt;
&lt;br /&gt;
  Nota. &amp;quot;inj f&amp;quot; es una abreviatura de &amp;quot;inj_on f UNIV&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Función suprayectiva:&lt;br /&gt;
  · surj_def: surj f ≡ ∀y. ∃x. y = f x&lt;br /&gt;
&lt;br /&gt;
  Función biyectiva:&lt;br /&gt;
  · bij_def: bij f ≡ inj f ∧ surj f&lt;br /&gt;
&lt;br /&gt;
  Propiedades de las funciones inversas:&lt;br /&gt;
  · inv_f_f:      inj f  ⟹ inv f (f x) = x&lt;br /&gt;
  · surj_f_inv_f: surj f ⟹ f (inv f y) = y&lt;br /&gt;
  · inv_inv_eq:   bij f  ⟹ inv (inv f) = f&lt;br /&gt;
&lt;br /&gt;
  Igualdad de funciones (por extensionalidad):&lt;br /&gt;
  · fun_eq_iff: (f = g) = (∀x. f x = g x)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de lema de demostración de propiedades de funciones: Una&lt;br /&gt;
  función inyectiva puede cancelarse en el lado izquierdo de la&lt;br /&gt;
  composición de funciones. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración applicativa›&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;inj f ⟹ (f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
  apply (simp add: inj_on_def fun_eq_iff) &lt;br /&gt;
    (* ∀x y. f x = f y ⟶ x = y ⟹&lt;br /&gt;
      (∀x. f (g x) = f (h x)) = (∀x. g x = h x)*)&lt;br /&gt;
  apply auto&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración applicativa sin auto›&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;inj f ⟹ (f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
  apply (unfold inj_on_def) &lt;br /&gt;
     (* ∀x∈UNIV. ∀y∈UNIV. f x = f y ⟶ x = y ⟹&lt;br /&gt;
        (f ∘ g = f ∘ h) = (g = h)*)&lt;br /&gt;
  apply (unfold fun_eq_iff) &lt;br /&gt;
     (* ∀x∈UNIV. ∀y∈UNIV. f x = f y ⟶ x = y ⟹&lt;br /&gt;
        (∀x. (f ∘ g) x = (f ∘ h) x) = (∀x. g x = h x))*)&lt;br /&gt;
  apply (unfold o_apply)&lt;br /&gt;
     (* ∀x∈UNIV. ∀y∈UNIV. f x = f y ⟶ x = y ⟹&lt;br /&gt;
        (∀x. f (g x) = f (h x)) = (∀x. g x = h x) *)&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
     (*  1. ⟦∀x∈UNIV. ∀y∈UNIV. f x = f y ⟶ x = y;&lt;br /&gt;
             ∀x. f (g x) = f (h x)⟧&lt;br /&gt;
            ⟹ ∀x. g x = h x&lt;br /&gt;
         2. ⟦∀x∈UNIV. ∀y∈UNIV. f x = f y ⟶ x = y;&lt;br /&gt;
             ∀x. g x = h x⟧&lt;br /&gt;
            ⟹ ∀x. f (g x) = f (h x)*)&lt;br /&gt;
   apply simp+&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;inj f&amp;quot;&lt;br /&gt;
  shows &amp;quot;(f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (auto simp add: inj_on_def fun_eq_iff) &lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;inj f&amp;quot;&lt;br /&gt;
  shows &amp;quot;(f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;f ∘ g = f ∘ h&amp;quot;&lt;br /&gt;
  show &amp;quot;g = h&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix x&lt;br /&gt;
    have &amp;quot;(f ∘ g)(x) = (f ∘ h)(x)&amp;quot; using `f ∘ g = f ∘ h` by simp&lt;br /&gt;
    then have &amp;quot;f(g(x)) = f(h(x))&amp;quot; by simp&lt;br /&gt;
    then show &amp;quot;g(x) = h(x)&amp;quot; using `inj f` by (simp add:inj_on_def)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;g = h&amp;quot;&lt;br /&gt;
  show &amp;quot;f ∘ g = f ∘ h&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix x&lt;br /&gt;
    have &amp;quot;(f ∘ g) x = f(g(x))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = f(h(x))&amp;quot; using `g = h` by simp&lt;br /&gt;
    also have &amp;quot;… = (f ∘ h) x&amp;quot; by simp&lt;br /&gt;
    finally show &amp;quot;(f ∘ g) x = (f ∘ h) x&amp;quot; by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;inj f&amp;quot;&lt;br /&gt;
  shows &amp;quot;(f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;f ∘ g = f ∘ h&amp;quot; &lt;br /&gt;
  then show &amp;quot;g = h&amp;quot; using `inj f` by (simp add: inj_on_def fun_eq_iff) &lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;g = h&amp;quot; &lt;br /&gt;
  then show &amp;quot;f ∘ g = f ∘ h&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection {* Función imagen *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Imagen de un conjunto mediante una función:&lt;br /&gt;
  · image_def: f ` A = {y. (∃x∈A. y = f x)}&lt;br /&gt;
&lt;br /&gt;
  Propiedades de la imagen:&lt;br /&gt;
  · image_compose: (f ∘ g)`r = f`g`r&lt;br /&gt;
  · image_Un:      f`(A ∪ B) = f`A ∪ f`B &lt;br /&gt;
  · image_Int:     inj f ⟹ f`(A ∩ B) = f`A ∩ f`B&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración de propiedades de la imagen:&lt;br /&gt;
     f`A ∪ g`A = (⋃x∈A. {f x, g x})&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;f`A ∪ g`A = (⋃x∈A. {f x, g x})&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración de propiedades de la imagen:&lt;br /&gt;
     f`{(x,y). P x y} = {f(x,y) | x y. P x y}&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;f`{(x,y). P x y} = {f(x,y) | x y. P x y}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El rango de una función (&amp;quot;range f&amp;quot;) es la imagen del universo &lt;br /&gt;
  (&amp;quot;f`UNIV&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
  Imagen inversa de un conjunto:&lt;br /&gt;
  · vimage_def: f -` B ≡ {x. f x ∈ B}&lt;br /&gt;
&lt;br /&gt;
  Propiedad de la imagen inversa de un conjunto:&lt;br /&gt;
  · vimage_Compl: f -` (-A) = -(f -` A)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Relaciones *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Relaciones básicas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La teoría de relaciones es HOL/Relation.thy.&lt;br /&gt;
&lt;br /&gt;
  Las relaciones son conjuntos de pares.&lt;br /&gt;
&lt;br /&gt;
  Relación identidad:&lt;br /&gt;
  · Id_def: Id ≡ {p. ∃x. p = (x,x)}&lt;br /&gt;
&lt;br /&gt;
  Composición de relaciones:&lt;br /&gt;
  · rel_comp_def: r O s ≡ {(x,z). ∃y. (x, y) ∈ r ∧ (y, z) ∈ s}&lt;br /&gt;
&lt;br /&gt;
  Propiedades:&lt;br /&gt;
  · R_O_Id:        R O Id = R&lt;br /&gt;
  · rel_comp_mono: ⟦r&amp;#039; ⊆ r; s&amp;#039; ⊆ s⟧ ⟹ (r&amp;#039; O s&amp;#039;) ⊆ (r O s)&lt;br /&gt;
&lt;br /&gt;
  Imagen inversa de una relación:&lt;br /&gt;
  · converse_iff: ((a,b) ∈ r^-1) = ((b,a) ∈ r)&lt;br /&gt;
&lt;br /&gt;
  Propiedad de la imagen inversa de una relación:&lt;br /&gt;
  · converse_rel_comp: (r O s)^-1 = s^-1 O r^-1&lt;br /&gt;
&lt;br /&gt;
  Imagen de un conjunto mediante una relación:&lt;br /&gt;
  · Image_iff: (b ∈ r``A) = (∃x:A. (x, b) ∈ r)&lt;br /&gt;
&lt;br /&gt;
  Dominio de una relación:&lt;br /&gt;
  · Domain_iff: (a ∈ Domain r) = (∃y. (a, y) ∈ r)&lt;br /&gt;
&lt;br /&gt;
  Rango de una relación:&lt;br /&gt;
  · Range_iff: (a ∈ Range r) = (∃y. (y,a) ∈ r)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Temas&amp;diff=670</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Temas&amp;diff=670"/>
		<updated>2019-05-13T08:43:52Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta página se encuentra el material (transparencias y teorías) del curso &amp;#039;&amp;#039;Lógica matemática y fundamentos&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
* Tema 1:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-1.pdf Sintaxis y semántica de la lógica proposicional].&lt;br /&gt;
* Tema 2:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-2.pdf Deducción natural proposicional].&lt;br /&gt;
* Tema 2a: [[Deducción natural proposicional con Isabelle/HOL]].&lt;br /&gt;
* Tema 2b: [[Deducción natural proposicional con Isabelle/HOL basada en tácticas]].&lt;br /&gt;
* Tema 3:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-3.pdf Sintaxis y semántica de la lógica de primer orden].&lt;br /&gt;
* Tema 4:  [https://www.cs.us.es/~jalonso/cursos/lmf-18/temas/tema-4.pdf Deducción natural en lógica de primer orden].&lt;br /&gt;
* Tema 4a: [https://www.glc.us.es/~jalonso/LMF2019/index.php/Tema_4a Deducción natural en lógica de primer orden con Isabelle/HOL].&lt;br /&gt;
* Tema 4b: [[Deducción natural en lógica de primer orden con Isabelle/HOL basada en tácticas]].&lt;br /&gt;
* Tema 5:  [[Programación funcional en Isabelle/HOL]].             &lt;br /&gt;
* Tema 6:  [https://www.cs.us.es/~jalonso/cursos/i1m/temas/tema-8.pdf Razonamiento sobre programas].    &lt;br /&gt;
* Tema 6a: [[Razonamiento sobre programas en Isabelle/HOL]].                  &lt;br /&gt;
* Tema 7:  [[Razonamiento por casos y por inducci¢n]].         &lt;br /&gt;
* Tema 8:  [[Razonamiento sobre árboles y bosques]].&lt;br /&gt;
* Tema 9:  [[Definiciones inductivas]].&lt;br /&gt;
* Tema 10: [[Conjuntos, funciones y relaciones]].&lt;br /&gt;
* Tema 11: [[Desarrollo de teorías formalizadas con Isabelle/HOL]].&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=668</id>
		<title>Desarrollo de teorías formalizadas con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=668"/>
		<updated>2019-05-13T08:43:26Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Desarrollo de teorías formalizadas *}&lt;br /&gt;
&lt;br /&gt;
theory T11_Desarrollo_de_teorias_formalizadas&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section {* Desarrollo de la teoría de grupos*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El objetivo de este tema es mostrar cómo se puede trabajar en&lt;br /&gt;
  estructuras algebraicas por medio de locales. Se usará como ejemplo la&lt;br /&gt;
  teoría de grupos. *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 1. Un grupo es una estructura (G,·,𝟭,^) tal que G es un&lt;br /&gt;
  conjunto, · es una operación binaria en G, 𝟭 es un elemento de G y ^&lt;br /&gt;
  es una función de G en G tales que se cumplen las siguientes&lt;br /&gt;
  propiedades:&lt;br /&gt;
  * asociativa: ∀x y z. x ⋅ (y ⋅ z) = (x ⋅ y) ⋅ z&lt;br /&gt;
  * neutro por la izquierda: ∀x. 𝟭 ⋅ x = x&lt;br /&gt;
  * inverso por la izquierda: ∀x. x^ ⋅ x = 𝟭 &lt;br /&gt;
  Definir el entorno axiomático de los grupos. *}&lt;br /&gt;
&lt;br /&gt;
locale grupo = &lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Notas sobre notación:&lt;br /&gt;
  * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
  * El neutro es 𝟭 y se escribe con \ y &amp;lt;one&amp;gt; (sin espacio entre ellos).&lt;br /&gt;
  * El inverso de x es x^ y se escribe con pulsando 2 veces en ^. *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  A continuación se crea un contexto en el que se supone la notación y&lt;br /&gt;
  axiomas de grupos. En el contexto se demuestran propiedades de los&lt;br /&gt;
  grupos. *}&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. En los grupos, x^ también es el inverso de x por la&lt;br /&gt;
  derecha; es decir &lt;br /&gt;
     x ⋅ x^ = 𝟭   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inverso_d: &lt;br /&gt;
  &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ x^ = 𝟭 ⋅ (x ⋅ x^)&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = (𝟭 ⋅ x) ⋅ x^&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (((x^)^ ⋅ x^) ⋅ x) ⋅ x^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ (x^ ⋅ x)) ⋅ x^&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ 𝟭) ⋅ x^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ (𝟭 ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ x^&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. En los grupos, 𝟭 también es el neutro por la derecha; es decir &lt;br /&gt;
     x ⋅ 𝟭 = x   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma neutro_d: &lt;br /&gt;
  &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ 𝟭 = x ⋅ (x^ ⋅ x)&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x ⋅ x^) ⋅ x&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⋅ x&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;… = x&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  finally show &amp;quot;x ⋅ 𝟭 = x&amp;quot; .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 3. En los grupos, se tiene la propiedad cancelativa por la&lt;br /&gt;
  izquierda; es decir,&lt;br /&gt;
     x ⋅ y = x ⋅ z syss y = z   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma cancelativa_i: &lt;br /&gt;
  &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;x ⋅ y = x ⋅ z&amp;quot;&lt;br /&gt;
  hence &amp;quot;x^ ⋅ (x ⋅ y) = x^ ⋅ (x ⋅ z)&amp;quot; by simp&lt;br /&gt;
  hence &amp;quot;(x^ ⋅ x) ⋅ y = (x^ ⋅ x) ⋅ z&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  hence &amp;quot;𝟭 ⋅ y = 𝟭 ⋅ z&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  thus &amp;quot;y = z&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;y = z&amp;quot;&lt;br /&gt;
  then show &amp;quot;x ⋅ y = x ⋅ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 4. En los grupos, el elemento neutro por la izquierda es&lt;br /&gt;
  único; es decir, si e es un elemento tal que para todo x se tiene que &lt;br /&gt;
  e ⋅ x = x, entonces e = 𝟭. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_neutro_i:&lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;𝟭 = x ⋅ x^&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = (e ⋅ x) ⋅ x^&amp;quot; using assms by simp&lt;br /&gt;
  also have &amp;quot;... = e ⋅ (x ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = e ⋅ 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = e&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 5. En los grupos, los inversos por la izquierda son únicos; es&lt;br /&gt;
  decir, si x&amp;#039; es un elemento tal que x&amp;#039; ⋅ x = 𝟭, entonces x^ x&amp;#039;. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_inverso_i:&lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x^ = 𝟭 ⋅ x^&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;... = (x&amp;#039; ⋅ x) ⋅ x^&amp;quot; using assms by simp&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ (x ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039;&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 6. En los grupos, es inverso de un producto es el producto de&lt;br /&gt;
  los inversos cambiados de orden; es decir,&lt;br /&gt;
     (x ⋅ y)^ = y^ ⋅ x^    *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inversa_producto:&lt;br /&gt;
  &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = 𝟭&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = (y^ ⋅ (x^ ⋅ x)) ⋅ y&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    also have &amp;quot;... = (y^ ⋅ 𝟭) ⋅ y&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    also have &amp;quot;... = y^ ⋅ y&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
    also have &amp;quot;... = 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 7. En los grupos, el inverso del inverso es el propio&lt;br /&gt;
  elemento; es decir, &lt;br /&gt;
     (x^)^ = x    *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
  using inverso_d unicidad_inverso_i by blast&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma inverso_inverso: &lt;br /&gt;
  &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;x ⋅ x^ = 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 8. En los grupos, la función inversa es inyectiva; es decir,&lt;br /&gt;
  si x e y tienen los mismos inversos, entonces son iguales. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis inverso_inverso)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática estructurada es›&lt;br /&gt;
lemma inversa_inyectiva:&lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(x^)^ = (y^)^&amp;quot; using assms by simp&lt;br /&gt;
  thus &amp;quot;x = y&amp;quot; by (simp only: inverso_inverso)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Teorías de órdenes mediante clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El tutorial sobre clases está en la teoría Clases.thy.&lt;br /&gt;
  &lt;br /&gt;
  La clase de los órdenes es la colección de los tipos que poseen una&lt;br /&gt;
  relación ≼ verificando las siguientes propiedades&lt;br /&gt;
  · reflexiva: x ≼ x&lt;br /&gt;
  · transitiva: ⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&lt;br /&gt;
  · antisimétrica: ⟦x ≼ y; y ≼ x⟧ ⟹ x = y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class orden = &lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≼&amp;quot; 50)&lt;br /&gt;
  assumes refl: &amp;quot;x ≼ x&amp;quot;&lt;br /&gt;
      and trans: &amp;quot;⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ≼ y; y ≼ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ha generado los teoremas correspondientes a los axiomas. Pueden consultarse&lt;br /&gt;
  mediante thm como se muestra a continuación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm trans&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se inicia el contexto orden en el que se van a realizar definiciones y&lt;br /&gt;
  demostraciones. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
context orden&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  x es menor que y si x es menor o igual que y y no son iguales.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition menor :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≺&amp;quot; 50)&lt;br /&gt;
  where &amp;quot;x ≺ y ⟷ x ≼ y ∧ ¬ y ≼ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    La relación menor es irreflexiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma irrefl: &amp;quot;¬ x ≺ x&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La relación menor es transitiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
    (* ⟦x ≼ y ∧ ¬ y ≼ x; y ≼ z ∧ ¬ z ≼ y⟧ ⟹ x ≼ z ∧ ¬ z ≼ x *)&lt;br /&gt;
  apply (auto intro: trans)&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma menor_trans: &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def intro: trans)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La relación menor es asimétrica; es decir, si x ≺ y e y ≺ x, entonces&lt;br /&gt;
  se verifica cualquier propiedad P. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma asimetrica: &amp;quot;x ≺ y ⟹ y ≺ x ⟹ P&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Subclase *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden lineal es un orden en que cada par de elementos son comparables.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class ordenLineal = orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ≼ y ∨ y ≼ x&amp;quot;&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los órdenes lineales se tiene que x ≺ y ∨ x = y ∨ y ≺ x.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
      (* (x ≼ y ∧ ¬ y ≼ x) ∨ x = y ∨ (y ≼ x ∧ ¬ x ≼ y) *)&lt;br /&gt;
  apply auto&lt;br /&gt;
      (*  1. ⟦x ≠ y; ¬ x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
          2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (cut_tac x=x and y=y in lineal)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y ∨ y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (erule disjE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply (erule_tac P=&amp;quot;x ≼ y&amp;quot; in notE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
  apply (drule antisim)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* 1. ⟦x ≼ y; y = x⟧ ⟹ x = y *)&lt;br /&gt;
  apply (erule sym)&lt;br /&gt;
      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  using menor_def lineal antisim  &lt;br /&gt;
  by blast&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Teoría de órdenes mediante ámbitos (&amp;quot;Locales&amp;quot;) *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden es una estructura con una relación reflexiva, transitiva y&lt;br /&gt;
  antisimétrica. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale Orden =&lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;⊑&amp;quot; 50)&lt;br /&gt;
  assumes refl:    &amp;quot;x ⊑ x&amp;quot;&lt;br /&gt;
      and trans:   &amp;quot;⟦x ⊑ y; y ⊑ z⟧ ⟹ x ⊑ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ⊑ y; y ⊑ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    Los teoremas se diferencian por el nombre y el ámbito. Por ejemplo,&lt;br /&gt;
    refl: ?x ≼ ?x&lt;br /&gt;
    Orden.refl: Orden ?menor_ig ⟹ ?menor_ig ?x ?x&lt;br /&gt;
    Orden_def: Orden ?menor_ig ≡&lt;br /&gt;
               (∀x. ?menor_ig x x) ∧&lt;br /&gt;
               (∀x y z. ?menor_ig x y ⟶ ?menor_ig y z ⟶ ?menor_ig x z) ∧&lt;br /&gt;
               (∀x y. ?menor_ig x y ⟶ ?menor_ig y x ⟶ x = y)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm refl&lt;br /&gt;
thm Orden.refl&lt;br /&gt;
thm Orden_def&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden lineal es un orden en el que todos los pares de elementos son &lt;br /&gt;
  comparables. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale OrdenLineal = Orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ⊑ y ∨ y ⊑ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los boooleanos está ordenados con el condicional.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_imp: Orden &amp;quot;λx y. x ⟶ y&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix P show &amp;quot;P ⟶ P&amp;quot; by blast&lt;br /&gt;
next&lt;br /&gt;
  fix P Q R show &amp;quot;P ⟶ Q ⟹ Q ⟶ R ⟹ P ⟶ R&amp;quot; by blast&lt;br /&gt;
next&lt;br /&gt;
  fix P Q show &amp;quot;P ⟶ Q ⟹ Q ⟶ P ⟹ P = Q&amp;quot; by blast&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales con la relación de divisibilidad es un conjunto ordenado.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_dvd: Orden &amp;quot;(dvd) :: nat ⇒ nat ⇒ bool&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x :: nat&lt;br /&gt;
  show &amp;quot;x dvd x&amp;quot; using dvd_refl by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x y z :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd z⟧ ⟹ x dvd z&amp;quot; using dvd_trans by auto&lt;br /&gt;
next&lt;br /&gt;
  fix x y :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd x⟧ ⟹ x = y&amp;quot; using dvd_antisym by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ámbito de las funciones monótonas (ver la página 12 del tutorial de&lt;br /&gt;
  locales). &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale Mono =&lt;br /&gt;
  le1: Orden le1 +&lt;br /&gt;
  le2: Orden le2 &lt;br /&gt;
    for le1 (infix &amp;quot;⊑⇩1&amp;quot; 50) and le2 (infix &amp;quot;⊑⇩2&amp;quot; 50) +&lt;br /&gt;
  fixes f :: &amp;quot;&amp;#039;a ⇒ &amp;#039;b&amp;quot;&lt;br /&gt;
  assumes mono: &amp;quot;x ⊑⇩1 y ⟹ f(x) ⊑⇩2 f(y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si f es monótona, x ⊑_1 y e y ⊑_1 z, entonces f(x) ⊑_2 f(z).&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in Mono) mono_trans: &lt;br /&gt;
  assumes &amp;quot;x ⊑⇩1 y&amp;quot; and &amp;quot;y ⊑⇩1 z&amp;quot; &lt;br /&gt;
  shows &amp;quot;f(x) ⊑⇩2 f(z)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⊑⇩1 z&amp;quot; using assms and le1.trans by blast&lt;br /&gt;
  then show &amp;quot;f(x) ⊑⇩2 f(z)&amp;quot; using mono by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El teorema generado se llama Mono.mono_trans.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm Mono.mono_trans&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En el contexto Mono el nombre es mono_trans.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
context Mono &lt;br /&gt;
begin &lt;br /&gt;
thm mono_trans &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El predicado `ser par&amp;#039; es un operador monótono entre los naturales con la&lt;br /&gt;
  relación de divisibilidad y los booleanos con el condicional; es decir, &lt;br /&gt;
     x dvd y ⟹ even x ⟶ even y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Mono &amp;quot;(dvd)&amp;quot; &amp;quot;(⟶)&amp;quot; &amp;quot;λn::nat. 2 dvd n&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix x y :: nat &lt;br /&gt;
  show &amp;quot;x dvd y ⟹ even x ⟶ even y&amp;quot;&lt;br /&gt;
    proof &lt;br /&gt;
      assume &amp;quot;x dvd y&amp;quot; and &amp;quot;even x&amp;quot;&lt;br /&gt;
      then show &amp;quot;even y&amp;quot; &lt;br /&gt;
        using  Rings.comm_monoid_mult_class.dvd_trans by auto&lt;br /&gt;
    qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Semigrupos, monoides y grupos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definición de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un semigrupo es una estructura compuesta por un conjunto A y una&lt;br /&gt;
  operación binaria en A.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class semigrupo =&lt;br /&gt;
  fixes mult :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⊗&amp;quot; 70) &lt;br /&gt;
  assumes asoc: &amp;quot;(x ⊗ y) ⊗ z = x ⊗ (y ⊗ z )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Instanciación de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los enteros con la suma forman un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation int :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
definition &lt;br /&gt;
  mult_int_def: &amp;quot;i ⊗ j = i + (j ::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i j k :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;(i + j ) + k = i + (j + k)&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;(i ⊗ j ) ⊗ k = i ⊗ (j ⊗ k)&amp;quot; unfolding mult_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales con la suma forman un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
primrec mult_nat where &lt;br /&gt;
  &amp;quot;(0::nat) ⊗ n = n&amp;quot; &lt;br /&gt;
| &amp;quot;Suc m ⊗ n = Suc (m ⊗ n)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix m n q :: &amp;quot;nat&amp;quot; &lt;br /&gt;
  show &amp;quot;m ⊗ n ⊗ q = m ⊗ (n ⊗ q)&amp;quot; &lt;br /&gt;
    by (induct m) auto&lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Instancias recursivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si (A,⊗) y (B,⊗) son semigrupos, entonces ((A×B,⊗), donde el producto&lt;br /&gt;
  se define por &lt;br /&gt;
     (x,y)⊗(x&amp;#039;,y&amp;#039;) = (x⊗x&amp;#039;,y⊗y&amp;#039;),&lt;br /&gt;
  es un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
 &lt;br /&gt;
instantiation prod :: (semigrupo, semigrupo) semigrupo &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  mult_prod_def : &amp;quot;p1 ⊗ p2 = (fst p1 ⊗ fst p2, snd p1 ⊗ snd p2)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p1 p2 p3 :: &amp;quot;&amp;#039;a::semigrupo × &amp;#039;b::semigrupo&amp;quot; &lt;br /&gt;
  show &amp;quot;(p1 ⊗ p2) ⊗ p3 = p1 ⊗ (p2 ⊗ p3)&amp;quot; &lt;br /&gt;
    unfolding mult_prod_def by (simp add: asoc) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Subclases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un monoide izquierdo es un semigrupo con elemento neutro por la izquierda. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class monoideI = semigrupo + &lt;br /&gt;
  fixes neutro :: &amp;quot;&amp;#039;a&amp;quot; (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
  assumes neutroI: &amp;quot;𝟭 ⊗ x = x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales y los enteros con la suma forman monoides por la izquierda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_nat_def : &amp;quot;𝟭 = (0::nat)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_int_def : &amp;quot;𝟭 = (0::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ n = n&amp;quot; unfolding neutro_nat_def by simp&lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ k = k&amp;quot; unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos monoides por la izquierda es un monoide por la&lt;br /&gt;
  izquierda, donde el neutro es el par formado por los elementos neutros.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoideI , monoideI) monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_prod_def : &amp;quot;𝟭 = (𝟭, 𝟭)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoideI × &amp;#039;b::monoideI&amp;quot; &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ p = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutroI) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un monoide es un monoide por la izquierda cuyo elemento neutro por la&lt;br /&gt;
  izquierda lo es también por la derecha.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class monoide = monoideI + &lt;br /&gt;
  assumes neutro: &amp;quot;x ⊗ 𝟭 = x&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales y los enteros con la suma son monoides.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;n ⊗ 𝟭 = n&amp;quot; &lt;br /&gt;
    unfolding neutro_nat_def by (induct n) simp_all &lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;k ⊗ 𝟭 = k&amp;quot; &lt;br /&gt;
    unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos monoides es un monoide.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoide, monoide) monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoide × &amp;#039;b::monoide&amp;quot; &lt;br /&gt;
  show &amp;quot;p ⊗ 𝟭 = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutro) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un grupo es un monoide por la izquierda tal que todo elemento posee un&lt;br /&gt;
  inverso por la izquierda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class grupo2 = monoideI + &lt;br /&gt;
  fixes inverso :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a&amp;quot; (&amp;quot;(_⇧-⇧1)&amp;quot; [1000] 999)&lt;br /&gt;
  assumes inversoI: &amp;quot;x⇧-⇧1 ⊗ x = 𝟭&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los enteros con la suma forman un grupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation int :: grupo2 &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition&lt;br /&gt;
  inverso_int_def: &amp;quot;i⇧-⇧1 = -(i::int)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;-i + i = 0&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;i⇧-⇧1 ⊗ i = 𝟭&amp;quot; &lt;br /&gt;
    unfolding mult_int_def neutro_int_def inverso_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Razonamiento abstracto *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los grupos se verifica la propiedad cancelativa por la izquierda, i.e.&lt;br /&gt;
     x ⊗ y = x ⊗ z ⟷ y = z&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in grupo2) cancelativa_izq: &amp;quot;x ⊗ y = x ⊗ z ⟷ y = z&amp;quot; &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;x ⊗ y = x ⊗ z&amp;quot;&lt;br /&gt;
  hence &amp;quot;x⇧-⇧1 ⊗ (x ⊗ y) = x⇧-⇧1 ⊗ (x ⊗ z)&amp;quot; by simp &lt;br /&gt;
  hence &amp;quot;(x⇧-⇧1 ⊗ x) ⊗ y = (x⇧-⇧1 ⊗ x) ⊗ z&amp;quot; using asoc by simp &lt;br /&gt;
  then show &amp;quot;y = z&amp;quot; using neutroI and inversoI by simp&lt;br /&gt;
next &lt;br /&gt;
  assume &amp;quot;y = z&amp;quot; &lt;br /&gt;
  then show &amp;quot;x ⊗ y = x ⊗ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
thm grupo2.cancelativa_izq&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se genera el teorema grupo.cancelativa_izq&lt;br /&gt;
     class.grupo2 ?mult ?neutro ?inverso ⟹ &lt;br /&gt;
     (?mult ?x ?y = ?mult ?x ?z) = (?y = ?z)&lt;br /&gt;
&lt;br /&gt;
  El teorema se aplica automáticamente a todas las instancias de la clase&lt;br /&gt;
  grupo. Por ejemplo, a los enteros.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definiciones derivadas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los monoides se define la potencia natural por&lt;br /&gt;
  · x^0     = 1&lt;br /&gt;
  · x^{n+1} = x*x^n&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun (in monoide) potencia_nat :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_nat 0 x       = 𝟭&amp;quot;  &lt;br /&gt;
| &amp;quot;potencia_nat (Suc n) x = x ⊗ potencia_nat n x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Analogía entre clases y functores *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;⋀x y z. (x @ y) @ z = x @ (y @ z)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. [] @ x = x&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. x @ [] = x&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se pueden aplicar propiedades de los monides a las listas. Por ejemplo,&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;append [] xs = xs&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  (repite n xs) es la lista obtenida concatenando n veces la lista xs. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where &lt;br /&gt;
  &amp;quot;repite 0 _        = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) xs = xs @ repite n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide. Además, la potencia natural se intepreta como&lt;br /&gt;
  repite. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; rewrites&lt;br /&gt;
  &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
proof -&lt;br /&gt;
  interpret monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; .. &lt;br /&gt;
  show &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
  proof &lt;br /&gt;
    fix n &lt;br /&gt;
    show &amp;quot;monoide.potencia_nat append [] n = repite n&amp;quot;&lt;br /&gt;
      by (induct n) auto &lt;br /&gt;
  qed &lt;br /&gt;
qed intro_locales&lt;br /&gt;
&lt;br /&gt;
subsection {* Relaciones de subclase adicionales *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los grupos son monoides.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subclass (in grupo2) monoide &lt;br /&gt;
proof &lt;br /&gt;
  fix x &lt;br /&gt;
  have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ (x ⊗ (x⇧-⇧1 ⊗ x))&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = (x⇧-⇧1 ⊗ x) ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; using asoc [symmetric] by simp&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = x⇧-⇧1 ⊗ x&amp;quot; using neutroI by simp&lt;br /&gt;
  finally have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ x&amp;quot; . &lt;br /&gt;
  then show &amp;quot;x ⊗ 𝟭 = x&amp;quot; using cancelativa_izq by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La potencia entera en los grupos se define a partir de la potencia natural&lt;br /&gt;
  como sigue:&lt;br /&gt;
  · x^k = x^k si k ≥ 0&lt;br /&gt;
  · x^k = (x^{-k})^{-1}, en caso contrario.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition (in grupo2) potencia_entera :: &amp;quot;int ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_entera k x = &lt;br /&gt;
   (if k &amp;gt;= 0 &lt;br /&gt;
    then potencia_nat (nat k) x &lt;br /&gt;
    else (potencia_nat (nat (- k)) x)⇧-⇧1)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
section {* Bibliografía *}&lt;br /&gt;
text {* &lt;br /&gt;
  + &amp;quot;Haskell-style type classes with Isabelle/Isar&amp;quot; ~ F. Haftmann.&lt;br /&gt;
    http://bit.ly/2E55pAJ&lt;br /&gt;
  + &amp;quot;Tutorial to locales and locale interpretation&amp;quot; ~ C. Ballarin.&lt;br /&gt;
    http://bit.ly/2E3ozXB  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C2%A1as_formalizadas_con_Isabelle/HOL&amp;diff=669</id>
		<title>Desarrollo de teor¡as formalizadas con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C2%A1as_formalizadas_con_Isabelle/HOL&amp;diff=669"/>
		<updated>2019-05-13T08:43:26Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECCIÓN [[Desarrollo de teorías formalizadas con Isabelle/HOL]]&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=667</id>
		<title>Desarrollo de teorías formalizadas con Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Desarrollo_de_teor%C3%ADas_formalizadas_con_Isabelle/HOL&amp;diff=667"/>
		<updated>2019-05-12T17:19:16Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Desarrollo de teorías formalizadas *}&lt;br /&gt;
&lt;br /&gt;
theory T11_Desarrollo_de_teorias_formalizadas&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section {* Desarrollo de la teoría de grupos*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El objetivo de este tema es mostrar cómo se puede trabajar en&lt;br /&gt;
  estructuras algebraicas por medio de locales. Se usará como ejemplo la&lt;br /&gt;
  teoría de grupos. *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 1. Un grupo es una estructura (G,·,𝟭,^) tal que G es un&lt;br /&gt;
  conjunto, · es una operación binaria en G, 𝟭 es un elemento de G y ^&lt;br /&gt;
  es una función de G en G tales que se cumplen las siguientes&lt;br /&gt;
  propiedades:&lt;br /&gt;
  * asociativa: ∀x y z. x ⋅ (y ⋅ z) = (x ⋅ y) ⋅ z&lt;br /&gt;
  * neutro por la izquierda: ∀x. 𝟭 ⋅ x = x&lt;br /&gt;
  * inverso por la izquierda: ∀x. x^ ⋅ x = 𝟭 &lt;br /&gt;
  Definir el entorno axiomático de los grupos. *}&lt;br /&gt;
&lt;br /&gt;
locale grupo = &lt;br /&gt;
  fixes prod :: &amp;quot;[&amp;#039;a, &amp;#039;a] ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⋅&amp;quot; 70)&lt;br /&gt;
    and neutro (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
    and inverso (&amp;quot;_^&amp;quot; [100] 100)&lt;br /&gt;
  assumes asociativa: &amp;quot;(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)&amp;quot;&lt;br /&gt;
      and neutro_i:   &amp;quot;𝟭 ⋅ x = x&amp;quot;&lt;br /&gt;
      and inverso_i:  &amp;quot;x^ ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Notas sobre notación:&lt;br /&gt;
  * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). &lt;br /&gt;
  * El neutro es 𝟭 y se escribe con \ y &amp;lt;one&amp;gt; (sin espacio entre ellos).&lt;br /&gt;
  * El inverso de x es x^ y se escribe con pulsando 2 veces en ^. *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  A continuación se crea un contexto en el que se supone la notación y&lt;br /&gt;
  axiomas de grupos. En el contexto se demuestran propiedades de los&lt;br /&gt;
  grupos. *}&lt;br /&gt;
&lt;br /&gt;
context grupo&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. En los grupos, x^ también es el inverso de x por la&lt;br /&gt;
  derecha; es decir &lt;br /&gt;
     x ⋅ x^ = 𝟭   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inverso_d: &lt;br /&gt;
  &amp;quot;x ⋅ x^ = 𝟭&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ x^ = 𝟭 ⋅ (x ⋅ x^)&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = (𝟭 ⋅ x) ⋅ x^&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (((x^)^ ⋅ x^) ⋅ x) ⋅ x^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ (x^ ⋅ x)) ⋅ x^&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = ((x^)^ ⋅ 𝟭) ⋅ x^&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ (𝟭 ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = (x^)^ ⋅ x^&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;… = 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. En los grupos, 𝟭 también es el neutro por la derecha; es decir &lt;br /&gt;
     x ⋅ 𝟭 = x   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma neutro_d: &lt;br /&gt;
  &amp;quot;x ⋅ 𝟭 = x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⋅ 𝟭 = x ⋅ (x^ ⋅ x)&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  also have &amp;quot;… = (x ⋅ x^) ⋅ x&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⋅ x&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;… = x&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  finally show &amp;quot;x ⋅ 𝟭 = x&amp;quot; .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 3. En los grupos, se tiene la propiedad cancelativa por la&lt;br /&gt;
  izquierda; es decir,&lt;br /&gt;
     x ⋅ y = x ⋅ z syss y = z   *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma cancelativa_i: &lt;br /&gt;
  &amp;quot;(x ⋅ y = x ⋅ z) = (y = z)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;x ⋅ y = x ⋅ z&amp;quot;&lt;br /&gt;
  hence &amp;quot;x^ ⋅ (x ⋅ y) = x^ ⋅ (x ⋅ z)&amp;quot; by simp&lt;br /&gt;
  hence &amp;quot;(x^ ⋅ x) ⋅ y = (x^ ⋅ x) ⋅ z&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  hence &amp;quot;𝟭 ⋅ y = 𝟭 ⋅ z&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
  thus &amp;quot;y = z&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;y = z&amp;quot;&lt;br /&gt;
  then show &amp;quot;x ⋅ y = x ⋅ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 4. En los grupos, el elemento neutro por la izquierda es&lt;br /&gt;
  único; es decir, si e es un elemento tal que para todo x se tiene que &lt;br /&gt;
  e ⋅ x = x, entonces e = 𝟭. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_neutro_i:&lt;br /&gt;
  assumes &amp;quot;e ⋅ x = x&amp;quot;&lt;br /&gt;
  shows &amp;quot;𝟭 = e&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;𝟭 = x ⋅ x^&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = (e ⋅ x) ⋅ x^&amp;quot; using assms by simp&lt;br /&gt;
  also have &amp;quot;... = e ⋅ (x ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = e ⋅ 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = e&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 5. En los grupos, los inversos por la izquierda son únicos; es&lt;br /&gt;
  decir, si x&amp;#039; es un elemento tal que x&amp;#039; ⋅ x = 𝟭, entonces x^ x&amp;#039;. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis asociativa inverso_i neutro_i)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma unicidad_inverso_i:&lt;br /&gt;
  assumes &amp;quot;x&amp;#039; ⋅ x = 𝟭&amp;quot;&lt;br /&gt;
  shows &amp;quot;x^ = x&amp;#039;&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x^ = 𝟭 ⋅ x^&amp;quot; by (simp only: neutro_i)&lt;br /&gt;
  also have &amp;quot;... = (x&amp;#039; ⋅ x) ⋅ x^&amp;quot; using assms by simp&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ (x ⋅ x^)&amp;quot; by (simp only: asociativa)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039; ⋅ 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
  also have &amp;quot;... = x&amp;#039;&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 6. En los grupos, es inverso de un producto es el producto de&lt;br /&gt;
  los inversos cambiados de orden; es decir,&lt;br /&gt;
     (x ⋅ y)^ = y^ ⋅ x^    *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
  by (metis asociativa inverso_d neutro_d)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma inversa_producto:&lt;br /&gt;
  &amp;quot;(x ⋅ y)^ = y^ ⋅ x^&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = 𝟭&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(y^ ⋅ x^) ⋅ (x ⋅ y) = (y^ ⋅ (x^ ⋅ x)) ⋅ y&amp;quot; by (simp only: asociativa)&lt;br /&gt;
    also have &amp;quot;... = (y^ ⋅ 𝟭) ⋅ y&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    also have &amp;quot;... = y^ ⋅ y&amp;quot; by (simp only: neutro_d)&lt;br /&gt;
    also have &amp;quot;... = 𝟭&amp;quot; by (simp only: inverso_i)&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 7. En los grupos, el inverso del inverso es el propio&lt;br /&gt;
  elemento; es decir, &lt;br /&gt;
     (x^)^ = x    *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
  using inverso_d unicidad_inverso_i by blast&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma inverso_inverso: &lt;br /&gt;
  &amp;quot;(x^)^ = x&amp;quot;&lt;br /&gt;
proof (rule unicidad_inverso_i)&lt;br /&gt;
  show &amp;quot;x ⋅ x^ = 𝟭&amp;quot; by (simp only: inverso_d)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 8. En los grupos, la función inversa es inyectiva; es decir,&lt;br /&gt;
  si x e y tienen los mismos inversos, entonces son iguales. *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es (obtenida con Sledgehammer) es›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
  using assms&lt;br /&gt;
  by (metis inverso_inverso)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática estructurada es›&lt;br /&gt;
lemma inversa_inyectiva:&lt;br /&gt;
  assumes &amp;quot;x^ = y^&amp;quot;&lt;br /&gt;
  shows &amp;quot;x = y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(x^)^ = (y^)^&amp;quot; using assms by simp&lt;br /&gt;
  thus &amp;quot;x = y&amp;quot; by (simp only: inverso_inverso)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Teorías de órdenes mediante clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El tutorial sobre clases está en la teoría Clases.thy.&lt;br /&gt;
  &lt;br /&gt;
  La clase de los órdenes es la colección de los tipos que poseen una&lt;br /&gt;
  relación ≼ verificando las siguientes propiedades&lt;br /&gt;
  · reflexiva: x ≼ x&lt;br /&gt;
  · transitiva: ⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&lt;br /&gt;
  · antisimétrica: ⟦x ≼ y; y ≼ x⟧ ⟹ x = y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class orden = &lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≼&amp;quot; 50)&lt;br /&gt;
  assumes refl: &amp;quot;x ≼ x&amp;quot;&lt;br /&gt;
      and trans: &amp;quot;⟦x ≼ y; y ≼ z⟧ ⟹ x ≼ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ≼ y; y ≼ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ha generado los teoremas correspondientes a los axiomas. Pueden consultarse&lt;br /&gt;
  mediante thm como se muestra a continuación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm trans&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se inicia el contexto orden en el que se van a realizar definiciones y&lt;br /&gt;
  demostraciones. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
context orden&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  x es menor que y si x es menor o igual que y y no son iguales.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition menor :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;≺&amp;quot; 50)&lt;br /&gt;
  where &amp;quot;x ≺ y ⟷ x ≼ y ∧ ¬ y ≼ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    La relación menor es irreflexiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma irrefl: &amp;quot;¬ x ≺ x&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La relación menor es transitiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
    (* ⟦x ≼ y ∧ ¬ y ≼ x; y ≼ z ∧ ¬ z ≼ y⟧ ⟹ x ≼ z ∧ ¬ z ≼ x *)&lt;br /&gt;
  apply (auto intro: trans)&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma menor_trans: &amp;quot;⟦x ≺ y; y ≺ z⟧ ⟹ x ≺ z&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def intro: trans)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La relación menor es asimétrica; es decir, si x ≺ y e y ≺ x, entonces&lt;br /&gt;
  se verifica cualquier propiedad P. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma asimetrica: &amp;quot;x ≺ y ⟹ y ≺ x ⟹ P&amp;quot;&lt;br /&gt;
  by (auto simp: menor_def)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Subclase *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden lineal es un orden en que cada par de elementos son comparables.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class ordenLineal = orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ≼ y ∨ y ≼ x&amp;quot;&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los órdenes lineales se tiene que x ≺ y ∨ x = y ∨ y ≺ x.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  apply (unfold menor_def)&lt;br /&gt;
      (* (x ≼ y ∧ ¬ y ≼ x) ∨ x = y ∨ (y ≼ x ∧ ¬ x ≼ y) *)&lt;br /&gt;
  apply auto&lt;br /&gt;
      (*  1. ⟦x ≠ y; ¬ x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
          2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (cut_tac x=x and y=y in lineal)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y ∨ y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply (erule disjE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; x ≼ y⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply (erule_tac P=&amp;quot;x ≼ y&amp;quot; in notE)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         3. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
    apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; ¬ x ≼ y; y ≼ x⟧ ⟹ y ≼ x&lt;br /&gt;
         2. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; y ≼ x; x ≼ y⟧ ⟹ False *)&lt;br /&gt;
  apply (drule antisim)&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y⟧ ⟹ x ≼ y&lt;br /&gt;
         2. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
      (* 1. ⟦x ≠ y; x ≼ y; y = x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
      (* 1. ⟦x ≼ y; y = x⟧ ⟹ x = y *)&lt;br /&gt;
  apply (erule sym)&lt;br /&gt;
      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;x ≺ y ∨ x = y ∨ y ≺ x&amp;quot;&lt;br /&gt;
  using menor_def lineal antisim  &lt;br /&gt;
  by blast&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Teoría de órdenes mediante ámbitos (&amp;quot;Locales&amp;quot;) *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden es una estructura con una relación reflexiva, transitiva y&lt;br /&gt;
  antisimétrica. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale Orden =&lt;br /&gt;
  fixes menor_ig :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ bool&amp;quot;  (infix &amp;quot;⊑&amp;quot; 50)&lt;br /&gt;
  assumes refl:    &amp;quot;x ⊑ x&amp;quot;&lt;br /&gt;
      and trans:   &amp;quot;⟦x ⊑ y; y ⊑ z⟧ ⟹ x ⊑ z&amp;quot;&lt;br /&gt;
      and antisim: &amp;quot;⟦x ⊑ y; y ⊑ x⟧ ⟹ x = y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    Los teoremas se diferencian por el nombre y el ámbito. Por ejemplo,&lt;br /&gt;
    refl: ?x ≼ ?x&lt;br /&gt;
    Orden.refl: Orden ?menor_ig ⟹ ?menor_ig ?x ?x&lt;br /&gt;
    Orden_def: Orden ?menor_ig ≡&lt;br /&gt;
               (∀x. ?menor_ig x x) ∧&lt;br /&gt;
               (∀x y z. ?menor_ig x y ⟶ ?menor_ig y z ⟶ ?menor_ig x z) ∧&lt;br /&gt;
               (∀x y. ?menor_ig x y ⟶ ?menor_ig y x ⟶ x = y)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm refl&lt;br /&gt;
thm Orden.refl&lt;br /&gt;
thm Orden_def&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un orden lineal es un orden en el que todos los pares de elementos son &lt;br /&gt;
  comparables. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale OrdenLineal = Orden +&lt;br /&gt;
  assumes lineal: &amp;quot;x ⊑ y ∨ y ⊑ x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los boooleanos está ordenados con el condicional.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_imp: Orden &amp;quot;λx y. x ⟶ y&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix P show &amp;quot;P ⟶ P&amp;quot; by blast&lt;br /&gt;
next&lt;br /&gt;
  fix P Q R show &amp;quot;P ⟶ Q ⟹ Q ⟶ R ⟹ P ⟶ R&amp;quot; by blast&lt;br /&gt;
next&lt;br /&gt;
  fix P Q show &amp;quot;P ⟶ Q ⟹ Q ⟶ P ⟹ P = Q&amp;quot; by blast&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales con la relación de divisibilidad es un conjunto ordenado.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Orden_dvd: Orden &amp;quot;(dvd) :: nat ⇒ nat ⇒ bool&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x :: nat&lt;br /&gt;
  show &amp;quot;x dvd x&amp;quot; using dvd_refl by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x y z :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd z⟧ ⟹ x dvd z&amp;quot; using dvd_trans by auto&lt;br /&gt;
next&lt;br /&gt;
  fix x y :: nat&lt;br /&gt;
  show &amp;quot;⟦x dvd y; y dvd x⟧ ⟹ x = y&amp;quot; using dvd_antisym by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ámbito de las funciones monótonas (ver la página 12 del tutorial de&lt;br /&gt;
  locales). &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
locale Mono =&lt;br /&gt;
  le1: Orden le1 +&lt;br /&gt;
  le2: Orden le2 &lt;br /&gt;
    for le1 (infix &amp;quot;⊑⇩1&amp;quot; 50) and le2 (infix &amp;quot;⊑⇩2&amp;quot; 50) +&lt;br /&gt;
  fixes f :: &amp;quot;&amp;#039;a ⇒ &amp;#039;b&amp;quot;&lt;br /&gt;
  assumes mono: &amp;quot;x ⊑⇩1 y ⟹ f(x) ⊑⇩2 f(y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si f es monótona, x ⊑_1 y e y ⊑_1 z, entonces f(x) ⊑_2 f(z).&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in Mono) mono_trans: &lt;br /&gt;
  assumes &amp;quot;x ⊑⇩1 y&amp;quot; and &amp;quot;y ⊑⇩1 z&amp;quot; &lt;br /&gt;
  shows &amp;quot;f(x) ⊑⇩2 f(z)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⊑⇩1 z&amp;quot; using assms and le1.trans by blast&lt;br /&gt;
  then show &amp;quot;f(x) ⊑⇩2 f(z)&amp;quot; using mono by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El teorema generado se llama Mono.mono_trans.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm Mono.mono_trans&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En el contexto Mono el nombre es mono_trans.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
context Mono &lt;br /&gt;
begin &lt;br /&gt;
thm mono_trans &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El predicado `ser par&amp;#039; es un operador monótono entre los naturales con la&lt;br /&gt;
  relación de divisibilidad y los booleanos con el condicional; es decir, &lt;br /&gt;
     x dvd y ⟹ even x ⟶ even y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Mono &amp;quot;(dvd)&amp;quot; &amp;quot;(⟶)&amp;quot; &amp;quot;λn::nat. 2 dvd n&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix x y :: nat &lt;br /&gt;
  show &amp;quot;x dvd y ⟹ even x ⟶ even y&amp;quot;&lt;br /&gt;
    proof &lt;br /&gt;
      assume &amp;quot;x dvd y&amp;quot; and &amp;quot;even x&amp;quot;&lt;br /&gt;
      then show &amp;quot;even y&amp;quot; &lt;br /&gt;
        using  Rings.comm_monoid_mult_class.dvd_trans by auto&lt;br /&gt;
    qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Semigrupos, monoides y grupos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definición de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un semigrupo es una estructura compuesta por un conjunto A y una&lt;br /&gt;
  operación binaria en A.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class semigrupo =&lt;br /&gt;
  fixes mult :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; (infixl &amp;quot;⊗&amp;quot; 70) &lt;br /&gt;
  assumes asoc: &amp;quot;(x ⊗ y) ⊗ z = x ⊗ (y ⊗ z )&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Instanciación de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los enteros con la suma forman un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation int :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
definition &lt;br /&gt;
  mult_int_def: &amp;quot;i ⊗ j = i + (j ::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i j k :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;(i + j ) + k = i + (j + k)&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;(i ⊗ j ) ⊗ k = i ⊗ (j ⊗ k)&amp;quot; unfolding mult_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales con la suma forman un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat :: semigrupo &lt;br /&gt;
begin &lt;br /&gt;
primrec mult_nat where &lt;br /&gt;
  &amp;quot;(0::nat) ⊗ n = n&amp;quot; &lt;br /&gt;
| &amp;quot;Suc m ⊗ n = Suc (m ⊗ n)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix m n q :: &amp;quot;nat&amp;quot; &lt;br /&gt;
  show &amp;quot;m ⊗ n ⊗ q = m ⊗ (n ⊗ q)&amp;quot; &lt;br /&gt;
    by (induct m) auto&lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Instancias recursivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si (A,⊗) y (B,⊗) son semigrupos, entonces ((A×B,⊗), donde el producto&lt;br /&gt;
  se define por &lt;br /&gt;
     (x,y)⊗(x&amp;#039;,y&amp;#039;) = (x⊗x&amp;#039;,y⊗y&amp;#039;),&lt;br /&gt;
  es un semigrupo.&lt;br /&gt;
*}&lt;br /&gt;
 &lt;br /&gt;
instantiation prod :: (semigrupo, semigrupo) semigrupo &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  mult_prod_def : &amp;quot;p1 ⊗ p2 = (fst p1 ⊗ fst p2, snd p1 ⊗ snd p2)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p1 p2 p3 :: &amp;quot;&amp;#039;a::semigrupo × &amp;#039;b::semigrupo&amp;quot; &lt;br /&gt;
  show &amp;quot;(p1 ⊗ p2) ⊗ p3 = p1 ⊗ (p2 ⊗ p3)&amp;quot; &lt;br /&gt;
    unfolding mult_prod_def by (simp add: asoc) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Subclases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un monoide izquierdo es un semigrupo con elemento neutro por la izquierda. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class monoideI = semigrupo + &lt;br /&gt;
  fixes neutro :: &amp;quot;&amp;#039;a&amp;quot; (&amp;quot;𝟭&amp;quot;) &lt;br /&gt;
  assumes neutroI: &amp;quot;𝟭 ⊗ x = x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales y los enteros con la suma forman monoides por la izquierda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_nat_def : &amp;quot;𝟭 = (0::nat)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_int_def : &amp;quot;𝟭 = (0::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ n = n&amp;quot; unfolding neutro_nat_def by simp&lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ k = k&amp;quot; unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos monoides por la izquierda es un monoide por la&lt;br /&gt;
  izquierda, donde el neutro es el par formado por los elementos neutros.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoideI , monoideI) monoideI &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_prod_def : &amp;quot;𝟭 = (𝟭, 𝟭)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoideI × &amp;#039;b::monoideI&amp;quot; &lt;br /&gt;
  show &amp;quot;𝟭 ⊗ p = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutroI) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un monoide es un monoide por la izquierda cuyo elemento neutro por la&lt;br /&gt;
  izquierda lo es también por la derecha.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class monoide = monoideI + &lt;br /&gt;
  assumes neutro: &amp;quot;x ⊗ 𝟭 = x&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los naturales y los enteros con la suma son monoides.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation nat and int :: monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;n ⊗ 𝟭 = n&amp;quot; &lt;br /&gt;
    unfolding neutro_nat_def by (induct n) simp_all &lt;br /&gt;
next &lt;br /&gt;
  fix k :: int &lt;br /&gt;
  show &amp;quot;k ⊗ 𝟭 = k&amp;quot; &lt;br /&gt;
    unfolding neutro_int_def mult_int_def by simp &lt;br /&gt;
qed&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos monoides es un monoide.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (monoide, monoide) monoide &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a::monoide × &amp;#039;b::monoide&amp;quot; &lt;br /&gt;
  show &amp;quot;p ⊗ 𝟭 = p&amp;quot; &lt;br /&gt;
    unfolding neutro_prod_def mult_prod_def by (simp add: neutro) &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Un grupo es un monoide por la izquierda tal que todo elemento posee un&lt;br /&gt;
  inverso por la izquierda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class grupo2 = monoideI + &lt;br /&gt;
  fixes inverso :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a&amp;quot; (&amp;quot;(_⇧-⇧1)&amp;quot; [1000] 999)&lt;br /&gt;
  assumes inversoI: &amp;quot;x⇧-⇧1 ⊗ x = 𝟭&amp;quot; &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los enteros con la suma forman un grupo.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation int :: grupo2 &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition&lt;br /&gt;
  inverso_int_def: &amp;quot;i⇧-⇧1 = -(i::int)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix i :: &amp;quot;int&amp;quot; &lt;br /&gt;
  have &amp;quot;-i + i = 0&amp;quot; by simp &lt;br /&gt;
  then show &amp;quot;i⇧-⇧1 ⊗ i = 𝟭&amp;quot; &lt;br /&gt;
    unfolding mult_int_def neutro_int_def inverso_int_def . &lt;br /&gt;
qed &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
subsection {* Razonamiento abstracto *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los grupos se verifica la propiedad cancelativa por la izquierda, i.e.&lt;br /&gt;
     x ⊗ y = x ⊗ z ⟷ y = z&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in grupo2) cancelativa_izq: &amp;quot;x ⊗ y = x ⊗ z ⟷ y = z&amp;quot; &lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;x ⊗ y = x ⊗ z&amp;quot;&lt;br /&gt;
  hence &amp;quot;x⇧-⇧1 ⊗ (x ⊗ y) = x⇧-⇧1 ⊗ (x ⊗ z)&amp;quot; by simp &lt;br /&gt;
  hence &amp;quot;(x⇧-⇧1 ⊗ x) ⊗ y = (x⇧-⇧1 ⊗ x) ⊗ z&amp;quot; using asoc by simp &lt;br /&gt;
  then show &amp;quot;y = z&amp;quot; using neutroI and inversoI by simp&lt;br /&gt;
next &lt;br /&gt;
  assume &amp;quot;y = z&amp;quot; &lt;br /&gt;
  then show &amp;quot;x ⊗ y = x ⊗ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
thm grupo2.cancelativa_izq&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se genera el teorema grupo.cancelativa_izq&lt;br /&gt;
     class.grupo2 ?mult ?neutro ?inverso ⟹ &lt;br /&gt;
     (?mult ?x ?y = ?mult ?x ?z) = (?y = ?z)&lt;br /&gt;
&lt;br /&gt;
  El teorema se aplica automáticamente a todas las instancias de la clase&lt;br /&gt;
  grupo. Por ejemplo, a los enteros.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definiciones derivadas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los monoides se define la potencia natural por&lt;br /&gt;
  · x^0     = 1&lt;br /&gt;
  · x^{n+1} = x*x^n&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun (in monoide) potencia_nat :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_nat 0 x       = 𝟭&amp;quot;  &lt;br /&gt;
| &amp;quot;potencia_nat (Suc n) x = x ⊗ potencia_nat n x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Analogía entre clases y functores *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  show &amp;quot;⋀x y z. (x @ y) @ z = x @ (y @ z)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. [] @ x = x&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀x. x @ [] = x&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se pueden aplicar propiedades de los monides a las listas. Por ejemplo,&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;append [] xs = xs&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  (repite n xs) es la lista obtenida concatenando n veces la lista xs. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where &lt;br /&gt;
  &amp;quot;repite 0 _        = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) xs = xs @ repite n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las listas con la operación de concatenación y la lista vacía como elemento&lt;br /&gt;
  neutro forman un monoide. Además, la potencia natural se intepreta como&lt;br /&gt;
  repite. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation list_monoide: monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; rewrites&lt;br /&gt;
  &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
proof -&lt;br /&gt;
  interpret monoide &amp;quot;append&amp;quot; &amp;quot;[]&amp;quot; .. &lt;br /&gt;
  show &amp;quot;monoide.potencia_nat append [] = repite&amp;quot; &lt;br /&gt;
  proof &lt;br /&gt;
    fix n &lt;br /&gt;
    show &amp;quot;monoide.potencia_nat append [] n = repite n&amp;quot;&lt;br /&gt;
      by (induct n) auto &lt;br /&gt;
  qed &lt;br /&gt;
qed intro_locales&lt;br /&gt;
&lt;br /&gt;
subsection {* Relaciones de subclase adicionales *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Los grupos son monoides.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subclass (in grupo2) monoide &lt;br /&gt;
proof &lt;br /&gt;
  fix x &lt;br /&gt;
  have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ (x ⊗ (x⇧-⇧1 ⊗ x))&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = (x⇧-⇧1 ⊗ x) ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; using asoc [symmetric] by simp&lt;br /&gt;
  also have &amp;quot;… = 𝟭 ⊗ (x⇧-⇧1 ⊗ x)&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;… = x⇧-⇧1 ⊗ x&amp;quot; using neutroI by simp&lt;br /&gt;
  finally have &amp;quot;x⇧-⇧1 ⊗ (x ⊗ 𝟭) = x⇧-⇧1 ⊗ x&amp;quot; . &lt;br /&gt;
  then show &amp;quot;x ⊗ 𝟭 = x&amp;quot; using cancelativa_izq by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La potencia entera en los grupos se define a partir de la potencia natural&lt;br /&gt;
  como sigue:&lt;br /&gt;
  · x^k = x^k si k ≥ 0&lt;br /&gt;
  · x^k = (x^{-k})^{-1}, en caso contrario.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition (in grupo2) potencia_entera :: &amp;quot;int ⇒ &amp;#039;a ⇒ &amp;#039;a&amp;quot; where &lt;br /&gt;
  &amp;quot;potencia_entera k x = &lt;br /&gt;
   (if k &amp;gt;= 0 &lt;br /&gt;
    then potencia_nat (nat k) x &lt;br /&gt;
    else (potencia_nat (nat (- k)) x)⇧-⇧1)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
section {* Bibliografía *}&lt;br /&gt;
text {* &lt;br /&gt;
  + &amp;quot;Haskell-style type classes with Isabelle/Isar&amp;quot; ~ F. Haftmann.&lt;br /&gt;
    http://bit.ly/2E55pAJ&lt;br /&gt;
  + &amp;quot;Tutorial to locales and locale interpretation&amp;quot; ~ C. Ballarin.&lt;br /&gt;
    http://bit.ly/2E3ozXB  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Conjuntos,_funciones_y_relaciones&amp;diff=664</id>
		<title>Conjuntos, funciones y relaciones</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Conjuntos,_funciones_y_relaciones&amp;diff=664"/>
		<updated>2019-05-09T06:48:59Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 10: Conjuntos, funciones y relaciones *}&lt;br /&gt;
&lt;br /&gt;
theory T10_Conjuntos_funciones_y_relaciones&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section {* Conjuntos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Operaciones con conjuntos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. La teoría elemental de conjuntos es HOL/Set.thy.&lt;br /&gt;
&lt;br /&gt;
  Nota. En un conjunto todos los elemento son del mismo tipo (por&lt;br /&gt;
  ejemplo, del tipo τ) y el conjunto tiene tipo (en el ejemplo, &amp;quot;τ set&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
  Reglas de la intersección:&lt;br /&gt;
  · IntI:  ⟦c ∈ A; c ∈ B⟧ ⟹ c ∈ A ∩ B&lt;br /&gt;
  · IntD1: c ∈ A ∩ B ⟹ c ∈ A&lt;br /&gt;
  · IntD2: c ∈ A ∩ B ⟹ c ∈ B&lt;br /&gt;
&lt;br /&gt;
  Nota. Propiedades del complementario:&lt;br /&gt;
  · Compl_iff: (c ∈ - A) = (c ∉ A)&lt;br /&gt;
  · Compl_Un:  - (A ∪ B) = - A ∩ - B&lt;br /&gt;
&lt;br /&gt;
  Nota. El conjunto vacío se representa por {} y el universal por UNIV. &lt;br /&gt;
&lt;br /&gt;
  Nota. Propiedades de la diferencia y del complementario:&lt;br /&gt;
  · Diff_disjoint:   A ∩ (B - A) = {}&lt;br /&gt;
  · Compl_partition: A ∪ - A = UNIV&lt;br /&gt;
&lt;br /&gt;
  Nota. Reglas de la relación de subconjunto:&lt;br /&gt;
  · subsetI: (⋀x. x ∈ A ⟹ x ∈ B) ⟹ A ⊆ B&lt;br /&gt;
  · subsetD: ⟦A ⊆ B; c ∈ A⟧ ⟹ c ∈ B   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo: A ∪ B ⊆ C syss A ⊆ C ∧ B ⊆ C.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(A ∪ B ⊆ C) = (A ⊆ C ∧ B ⊆ C)&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo: A ⊆ -B syss B ⊆ -A.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(A ⊆ -B) = (B ⊆ -A)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Principio de extensionalidad de conjuntos:&lt;br /&gt;
  · set_eqI: (⋀x. (x ∈ A) = (x ∈ B)) ⟹ A = B&lt;br /&gt;
&lt;br /&gt;
  Reglas de la igualdad de conjuntos:&lt;br /&gt;
  · equalityI:  ⟦A ⊆ B; B ⊆ A⟧ ⟹ A = B&lt;br /&gt;
  · equalityD1: A = B ⟹ A ⊆ B&lt;br /&gt;
  · equalityD2: A = B ⟹ B ⊆ A &lt;br /&gt;
  · equalityE:  ⟦A = B; ⟦A ⊆ B; B ⊆ A⟧ ⟹ P⟧ ⟹ P   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre intersección y conjunción]&lt;br /&gt;
  &amp;quot;x ∈ A ∩ B&amp;quot; syss &amp;quot;x ∈ A&amp;quot; y &amp;quot;x ∈ B&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(x ∈ A ∩ B) = (x ∈ A ∧ x ∈ B)&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre unión y disyunción]&lt;br /&gt;
  x ∈ A ∪ B syss x ∈ A ó x ∈ B.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(x ∈ A ∪ B) = (x ∈ A ∨ x ∈ B)&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre subconjunto e implicación]&lt;br /&gt;
  A ⊆ B syss para todo x, si x ∈ A entonces x ∈ B.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(A ⊆ B) = (∀ x. x ∈ A ⟶ x ∈ B)&amp;quot; &lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Analogía entre complementario y negación]&lt;br /&gt;
  x pertenece al complementario de A syss x no pertenece a A.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(x ∈ -A) = (x ∉ A)&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
subsection {* Notación de conjuntos finitos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. La teoría de conjuntos finitos es HOL/Finite_Set.thy.&lt;br /&gt;
&lt;br /&gt;
  Nota. Los conjuntos finitos se definen por inducción a partir de las&lt;br /&gt;
  siguientes reglas inductivas:&lt;br /&gt;
  · El conjunto vacío es un conjunto finito.&lt;br /&gt;
    · emptyI: &amp;quot;finite {}&amp;quot;&lt;br /&gt;
  · Si se le añade un elemento a un conjunto finito se obtiene otro&lt;br /&gt;
    conjunto finito. &lt;br /&gt;
    · insertI: &amp;quot;finite A ⟹ finite (insert a A)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
  A continuación se muestran ejemplos de conjuntos finitos.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;insert 2 {} = {2} ∧&lt;br /&gt;
   insert 3 {2} = {2,3} ∧&lt;br /&gt;
   insert 2 {2,3} = {2,3} ∧&lt;br /&gt;
   {2,3} = {3,2,3,2,2}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. Los conjuntos finitos se representan con la notación conjuntista&lt;br /&gt;
  habitual: los elementos entre llaves y separados por comas. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo: {a,b} ∪ {c,d} = {a,b,c,d}   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{a,b} ∪ {c,d} = {a,b,c,d}&amp;quot; &lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de conjetura falsa y su refutación. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{a,b} ∩ {b,c} = {b}&amp;quot; &lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
(* Auto Quickcheck found a counterexample:&lt;br /&gt;
    a = a⇩1&lt;br /&gt;
    b = a⇩2&lt;br /&gt;
    c = a⇩1&lt;br /&gt;
   Evaluated terms:&lt;br /&gt;
    {a, b} ∩ {b, c} = {a⇩2, a⇩1}&lt;br /&gt;
    {b} = {a⇩2}&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo con la conjetura corregida.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{a,b} ∩ {b,c} = (if a = c then {a,b} else {b})&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Sumas de conjuntos finitos:&lt;br /&gt;
  · ∑A es la suma de los elementos del conjunto finito A. Por ejemplo, &lt;br /&gt;
      value &amp;quot;∑{1,2,3}::int&amp;quot; -- &amp;quot;= 6&amp;quot;&lt;br /&gt;
  · (setsum f A) es la suma de la aplicación de f a los elementos del&lt;br /&gt;
    conjunto finito A,  Por ejemplo,&lt;br /&gt;
       value &amp;quot;setsum (λx. x*x) {1,2,3}::int&amp;quot; -- &amp;quot;= 14&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplos de definiciones recursivas sobre conjuntos finitos: &lt;br /&gt;
  Sea A un conjunto finito de números naturales.&lt;br /&gt;
  · sumaConj A es la suma de los elementos A.&lt;br /&gt;
  · sumaCuadradosConj A es la suma de los cuadrados de los elementos A. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition sumaConj :: &amp;quot;nat set ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sumaConj S ≡ ∑S&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sumaConj {2,5,3}&amp;quot; ― ‹= 10›&lt;br /&gt;
value &amp;quot;∑{2::nat,5,3}&amp;quot; ― ‹= 10›&lt;br /&gt;
&lt;br /&gt;
definition sumaCuadradosConj :: &amp;quot;nat set ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sumaCuadradosConj S ≡ ∑x∈S. x*x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sumaCuadradosConj {2,5,3}&amp;quot; ― ‹= 38›&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. Para simplificar lo que sigue, declaramos las anteriores&lt;br /&gt;
  definiciones como reglas de simplificación.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
declare sumaConj_def [simp]&lt;br /&gt;
declare sumaCuadradosConj_def [simp]&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplos de evaluación de las anteriores definiciones recursivas.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;sumaConj {1,2,3,4} = 10 ∧&lt;br /&gt;
   sumaCuadradosConj {1,2,3,4} = 30&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Inducción sobre conjuntos finitos: Para demostrar que todos los&lt;br /&gt;
  conjuntos finitos tienen una propiedad P basta probar que&lt;br /&gt;
  · El conjunto vacío tiene la propiedad P.&lt;br /&gt;
  · Si a un conjunto finito que tiene la propiedad P se le añade un&lt;br /&gt;
    nuevo elemento, el conjunto obtenido sigue teniendo la propiedad P. &lt;br /&gt;
  En forma de regla&lt;br /&gt;
  · finite_induct: ⟦finite F; &lt;br /&gt;
                    P {}; &lt;br /&gt;
                    ⋀x F. ⟦finite F; x ∉ F; P F⟧ ⟹ P ({x} ∪ F)⟧ &lt;br /&gt;
                   ⟹ P F   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de inducción sobre conjuntos finitos: Sea S un conjunto finito&lt;br /&gt;
  de números naturales. Entonces todos los elementos de S son menores o&lt;br /&gt;
  iguales que la suma de los elementos de S. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;finite S ⟹ ∀x∈S. x ≤ sumaConj S&amp;quot;&lt;br /&gt;
  apply (induct rule: finite_induct)&lt;br /&gt;
     (* 1. ∀x∈{}. x ≤ sumaConj {}&lt;br /&gt;
        2. ⋀x F. ⟦finite F; x ∉ F; ∀x∈F. x ≤ sumaConj F⟧&lt;br /&gt;
                 ⟹ ∀xa∈insert x F. xa ≤ sumaConj (insert x F) *)&lt;br /&gt;
   apply auto&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;finite S ⟹ ∀x∈S. x ≤ sumaConj S&amp;quot;&lt;br /&gt;
  by (induct rule: finite_induct) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma sumaConj_acota: &lt;br /&gt;
  &amp;quot;finite S ⟹ ∀x∈S. x ≤ sumaConj S&amp;quot;&lt;br /&gt;
proof (induct rule: finite_induct)&lt;br /&gt;
  show &amp;quot;∀x ∈ {}. x ≤ sumaConj {}&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x and F&lt;br /&gt;
  assume fF: &amp;quot;finite F&amp;quot; &lt;br /&gt;
     and xF: &amp;quot;x ∉ F&amp;quot; &lt;br /&gt;
     and HI: &amp;quot;∀ x∈F. x ≤ sumaConj F&amp;quot;&lt;br /&gt;
  show &amp;quot;∀y ∈ insert x F. y ≤ sumaConj (insert x F)&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    fix y &lt;br /&gt;
    assume &amp;quot;y ∈ insert x F&amp;quot;&lt;br /&gt;
    show &amp;quot;y ≤ sumaConj (insert x F)&amp;quot;&lt;br /&gt;
    proof (cases &amp;quot;y = x&amp;quot;)&lt;br /&gt;
      assume &amp;quot;y = x&amp;quot;&lt;br /&gt;
      then have &amp;quot;y ≤ x + (sumaConj F)&amp;quot; by simp&lt;br /&gt;
      also have &amp;quot;… = sumaConj (insert x F)&amp;quot; using fF xF by simp&lt;br /&gt;
      finally show ?thesis .&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;y ≠ x&amp;quot;&lt;br /&gt;
      then have &amp;quot;y ∈ F&amp;quot; using `y ∈ insert x F` by simp&lt;br /&gt;
      then have &amp;quot;y ≤ sumaConj F&amp;quot; using HI by blast&lt;br /&gt;
      also have &amp;quot;… ≤ x + (sumaConj F)&amp;quot; by simp&lt;br /&gt;
      also have &amp;quot;… = sumaConj (insert x F)&amp;quot; using fF xF by simp&lt;br /&gt;
      finally show ?thesis .&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection {* Definiciones por comprensión *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El conjunto de los elementos que cumple la propiedad P se representa&lt;br /&gt;
  por {x. P}. &lt;br /&gt;
&lt;br /&gt;
  Reglas de comprensión (relación entre colección y pertenencia):&lt;br /&gt;
  · mem_Collect_eq: (a ∈ {x. P x}) = P a&lt;br /&gt;
  · Collect_mem_eq: {x. x ∈ A} = A   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de comprensión: {x. P x ∨ x ∈ A} = {x. P x} ∪ A   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{x. P x ∨ x ∈ A} = {x. P x} ∪ A&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de comprensión: {x. P x ⟶ Q x} = -{x. P x} ∪ {x. Q x}   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;{x. P x ⟶ Q x} = -{x. P x} ∪ {x. Q x}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo con la sintaxis general de comprensión.   &lt;br /&gt;
     {p*q | p q. p ∈ prime ∧ q ∈ prime} = &lt;br /&gt;
     {z. ∃p q. z = p*q ∧ p ∈ prime ∧ q ∈ prime}   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;{p*q | p q. p ∈ prime ∧ q ∈ prime} = &lt;br /&gt;
   {z. ∃p q. z = p*q ∧ p ∈ prime ∧ q ∈ prime}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
   En HOL, la notación conjuntista es azúcar sintáctica:&lt;br /&gt;
   · x ∈ A  es equivalente a A(x).&lt;br /&gt;
   · {x. P} es equivalente a λx. P.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de definición por comprensión: El conjunto de los pares es el&lt;br /&gt;
  de los números n para los que existe un m tal que n = 2*m.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition Pares :: &amp;quot;nat set&amp;quot; where&lt;br /&gt;
  &amp;quot;Pares ≡ {n. ∃m. n = 2*m }&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo. Los números 2 y 34 son pares.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;2 ∈ Pares ∧&lt;br /&gt;
   34 ∈ Pares&amp;quot; &lt;br /&gt;
  by (simp add: Pares_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Definición. El conjunto de los impares es el de los números n para los&lt;br /&gt;
  que existe un m tal que n = 2*m + 1.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition Impares :: &amp;quot;nat set&amp;quot; where&lt;br /&gt;
  &amp;quot;Impares ≡ {n. ∃m. n = 2*m + 1}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo con las reglas de intersección y comprensión: El conjunto de&lt;br /&gt;
  los pares es disjunto con el de los impares. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  apply auto&lt;br /&gt;
    (* ⟦x ∈ Pares; x ∈ Impares⟧ ⟹ False *)&lt;br /&gt;
  apply (simp add: Pares_def Impares_def)&lt;br /&gt;
    (* ⟦∃m. x = 2 * m; ∃m. x = Suc (2 * m)⟧ ⟹ False *)&lt;br /&gt;
  apply arith&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  by (auto simp add: Pares_def Impares_def, arith)&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x assume S: &amp;quot;x ∈ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  then have &amp;quot;x ∈ Pares&amp;quot; by (rule IntD1)&lt;br /&gt;
  then have &amp;quot;∃m. x = 2 * m&amp;quot; by (simp only: Pares_def mem_Collect_eq)&lt;br /&gt;
  then obtain p where p: &amp;quot;x = 2 * p&amp;quot; .. &lt;br /&gt;
  from S have &amp;quot;x ∈ Impares&amp;quot; by (rule IntD2)&lt;br /&gt;
  then have &amp;quot;∃ m. x = 2 * m + 1&amp;quot; by (simp only: Impares_def mem_Collect_eq)&lt;br /&gt;
  then obtain q where q: &amp;quot;x = 2 * q + 1&amp;quot; .. &lt;br /&gt;
  from p and q show &amp;quot;False&amp;quot; by arith&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración declarativa›&lt;br /&gt;
lemma &amp;quot;x ∉ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix x assume S: &amp;quot;x ∈ (Pares ∩ Impares)&amp;quot;&lt;br /&gt;
  then have &amp;quot;x ∈ Pares&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;∃m. x = 2 * m&amp;quot; by (simp only: Pares_def mem_Collect_eq)&lt;br /&gt;
  then obtain p where p: &amp;quot;x = 2 * p&amp;quot; .. &lt;br /&gt;
  from S have &amp;quot;x ∈ Impares&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;∃ m. x = 2 * m + 1&amp;quot; by (simp only: Impares_def mem_Collect_eq)&lt;br /&gt;
  then obtain q where q: &amp;quot;x = 2 * q + 1&amp;quot; .. &lt;br /&gt;
  from p and q show &amp;quot;False&amp;quot; by arith&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection {* Cuantificadores acotados *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Reglas de cuantificador universal acotado (&amp;quot;bounded&amp;quot;):&lt;br /&gt;
  · ballI: (⋀x. x ∈ A ⟹ P x) ⟹ ∀x∈A. P x&lt;br /&gt;
  · bspec: ⟦∀x∈A. P x; x ∈ A⟧ ⟹ P x&lt;br /&gt;
&lt;br /&gt;
  Reglas de cuantificador existencial acotado (&amp;quot;bounded&amp;quot;):&lt;br /&gt;
  · bexI: ⟦P x; x ∈ A⟧ ⟹ ∃x∈A. P x&lt;br /&gt;
  · bexE: ⟦∃x∈A. P x; ⋀x. ⟦x ∈ A; P x⟧ ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  Reglas de la unión indexada:&lt;br /&gt;
  · UN_iff: (b ∈ (⋃x∈A. B x)) = (∃x∈A. b ∈ B x)&lt;br /&gt;
  · UN_I:   ⟦a ∈ A; b ∈ B a⟧ ⟹ b ∈ (⋃x∈A. B x)&lt;br /&gt;
  · UN_E:   ⟦b ∈ (⋃x∈A. B x); ⋀x. ⟦x ∈ A; b ∈ B x⟧ ⟹ R⟧ ⟹ R&lt;br /&gt;
&lt;br /&gt;
  Reglas de la unión de una familia:&lt;br /&gt;
  · Union_def: ⋃S = (⋃x∈S. x)&lt;br /&gt;
  · Union_iff: (A ∈ ⋃C) = (∃X∈C. A ∈ X)&lt;br /&gt;
&lt;br /&gt;
  Reglas de la intersección indexada:&lt;br /&gt;
  · INT_iff: (b ∈ (⋂x∈A. B x)) = (∀x∈A. b ∈ B x)&lt;br /&gt;
  · INT_I:   (⋀x. x ∈ A ⟹ b ∈ B x) ⟹ b ∈ (⋂x∈A. B x)&lt;br /&gt;
  · INT_E:   ⟦b ∈ (⋂x∈A. B x); b ∈ B a ⟹ R; a ∉ A ⟹ R⟧ ⟹ R&lt;br /&gt;
&lt;br /&gt;
  Reglas de la intersección de una familia:&lt;br /&gt;
  · Inter_def: ⋂S = (⋂x∈S. x)&lt;br /&gt;
  · Inter_iff: (A ∈ ⋂C) = (∀X∈C. A ∈ X)&lt;br /&gt;
&lt;br /&gt;
  Abreviaturas:&lt;br /&gt;
  · &amp;quot;Collect P&amp;quot; es lo mismo que &amp;quot;{x. P}&amp;quot;.&lt;br /&gt;
  · &amp;quot;All P&amp;quot;     es lo mismo que &amp;quot;∀x. P x&amp;quot;.&lt;br /&gt;
  · &amp;quot;Ex P&amp;quot;      es lo mismo que &amp;quot;∃x. P x&amp;quot;.&lt;br /&gt;
  · &amp;quot;Ball A P&amp;quot;  es lo mismo que &amp;quot;∀x∈A. P x&amp;quot;.&lt;br /&gt;
  · &amp;quot;Bex A P&amp;quot;   es lo mismo que &amp;quot;∃x∈A. P x&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Conjuntos finitos y cardinalidad *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El número de elementos de un conjunto finito A es el cardinal de A y&lt;br /&gt;
  se representa por &amp;quot;card A&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplos de cardinales de conjuntos finitos.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;card {} = 0 ∧&lt;br /&gt;
   card {4} = 1 ∧&lt;br /&gt;
   card {4,1} = 2 ∧&lt;br /&gt;
   x ≠ y ⟹ card {x,y} = 2&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Propiedades de cardinales:&lt;br /&gt;
  · Cardinal de la unión de conjuntos finitos:&lt;br /&gt;
    card_Un_Int: ⟦finite A; finite B⟧ &lt;br /&gt;
                 ⟹ card A + card B = card (A ∪ B) + card (A ∩ B)&amp;quot; &lt;br /&gt;
  · Cardinal del conjunto potencia: &lt;br /&gt;
    card_Pow: finite A ⟹ card (Pow A) = 2 ^ card A&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Funciones *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  La teoría de funciones es HOL/Fun.thy. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Nociones básicas de funciones *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Principio de extensionalidad para funciones:&lt;br /&gt;
  · ext: (⋀x. f x = g x) ⟹ f = g&lt;br /&gt;
&lt;br /&gt;
  Actualización de funciones  &lt;br /&gt;
  · fun_upd_apply: (f(x := y)) z = (if z = x then y else f z)&lt;br /&gt;
  · fun_upd_upd:   f(x := y, x := z) = f(x := z)&lt;br /&gt;
&lt;br /&gt;
  Función identidad&lt;br /&gt;
  · id_def: id ≡ λx. x&lt;br /&gt;
&lt;br /&gt;
  Composición de funciones:&lt;br /&gt;
  · o_def: f ∘ g = (λx. f (g x))&lt;br /&gt;
&lt;br /&gt;
  Asociatividad de la composición:&lt;br /&gt;
  · o_assoc: f ∘ (g ∘ h) = (f ∘ g) ∘ h&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Funciones inyectivas, suprayectivas y biyectivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Función inyectiva sobre A:&lt;br /&gt;
  · inj_on_def: inj_on f A ≡ ∀x∈A. ∀y∈A. f x = f y ⟶ x = y&lt;br /&gt;
&lt;br /&gt;
  Nota. &amp;quot;inj f&amp;quot; es una abreviatura de &amp;quot;inj_on f UNIV&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
  Función suprayectiva:&lt;br /&gt;
  · surj_def: surj f ≡ ∀y. ∃x. y = f x&lt;br /&gt;
&lt;br /&gt;
  Función biyectiva:&lt;br /&gt;
  · bij_def: bij f ≡ inj f ∧ surj f&lt;br /&gt;
&lt;br /&gt;
  Propiedades de las funciones inversas:&lt;br /&gt;
  · inv_f_f:      inj f  ⟹ inv f (f x) = x&lt;br /&gt;
  · surj_f_inv_f: surj f ⟹ f (inv f y) = y&lt;br /&gt;
  · inv_inv_eq:   bij f  ⟹ inv (inv f) = f&lt;br /&gt;
&lt;br /&gt;
  Igualdad de funciones (por extensionalidad):&lt;br /&gt;
  · fun_eq_iff: (f = g) = (∀x. f x = g x)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de lema de demostración de propiedades de funciones: Una&lt;br /&gt;
  función inyectiva puede cancelarse en el lado izquierdo de la&lt;br /&gt;
  composición de funciones. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración applicativa›&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;inj f ⟹ (f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
  apply (simp add: inj_on_def fun_eq_iff) &lt;br /&gt;
  apply auto&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;inj f&amp;quot;&lt;br /&gt;
  shows &amp;quot;(f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by (auto simp add: inj_on_def fun_eq_iff) &lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;inj f&amp;quot;&lt;br /&gt;
  shows &amp;quot;(f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;f ∘ g = f ∘ h&amp;quot;&lt;br /&gt;
  show &amp;quot;g = h&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix x&lt;br /&gt;
    have &amp;quot;(f ∘ g)(x) = (f ∘ h)(x)&amp;quot; using `f ∘ g = f ∘ h` by simp&lt;br /&gt;
    then have &amp;quot;f(g(x)) = f(h(x))&amp;quot; by simp&lt;br /&gt;
    then show &amp;quot;g(x) = h(x)&amp;quot; using `inj f` by (simp add:inj_on_def)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;g = h&amp;quot;&lt;br /&gt;
  show &amp;quot;f ∘ g = f ∘ h&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix x&lt;br /&gt;
    have &amp;quot;(f ∘ g) x = f(g(x))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = f(h(x))&amp;quot; using `g = h` by simp&lt;br /&gt;
    also have &amp;quot;… = (f ∘ h) x&amp;quot; by simp&lt;br /&gt;
    finally show &amp;quot;(f ∘ g) x = (f ∘ h) x&amp;quot; by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  assumes &amp;quot;inj f&amp;quot;&lt;br /&gt;
  shows &amp;quot;(f ∘ g = f ∘ h) = (g = h)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;f ∘ g = f ∘ h&amp;quot; &lt;br /&gt;
  then show &amp;quot;g = h&amp;quot; using `inj f` by (simp add: inj_on_def fun_eq_iff) &lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;g = h&amp;quot; &lt;br /&gt;
  then show &amp;quot;f ∘ g = f ∘ h&amp;quot; by auto&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsubsection {* Función imagen *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Imagen de un conjunto mediante una función:&lt;br /&gt;
  · image_def: f ` A = {y. (∃x∈A. y = f x)}&lt;br /&gt;
&lt;br /&gt;
  Propiedades de la imagen:&lt;br /&gt;
  · image_compose: (f ∘ g)`r = f`g`r&lt;br /&gt;
  · image_Un:      f`(A ∪ B) = f`A ∪ f`B &lt;br /&gt;
  · image_Int:     inj f ⟹ f`(A ∩ B) = f`A ∩ f`B&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración de propiedades de la imagen:&lt;br /&gt;
     f`A ∪ g`A = (⋃x∈A. {f x, g x})&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;f`A ∪ g`A = (⋃x∈A. {f x, g x})&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración de propiedades de la imagen:&lt;br /&gt;
     f`{(x,y). P x y} = {f(x,y) | x y. P x y}&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;f`{(x,y). P x y} = {f(x,y) | x y. P x y}&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El rango de una función (&amp;quot;range f&amp;quot;) es la imagen del universo &lt;br /&gt;
  (&amp;quot;f`UNIV&amp;quot;). &lt;br /&gt;
&lt;br /&gt;
  Imagen inversa de un conjunto:&lt;br /&gt;
  · vimage_def: f -` B ≡ {x. f x ∈ B}&lt;br /&gt;
&lt;br /&gt;
  Propiedad de la imagen inversa de un conjunto:&lt;br /&gt;
  · vimage_Compl: f -` (-A) = -(f -` A)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Relaciones *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Relaciones básicas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La teoría de relaciones es HOL/Relation.thy.&lt;br /&gt;
&lt;br /&gt;
  Las relaciones son conjuntos de pares.&lt;br /&gt;
&lt;br /&gt;
  Relación identidad:&lt;br /&gt;
  · Id_def: Id ≡ {p. ∃x. p = (x,x)}&lt;br /&gt;
&lt;br /&gt;
  Composición de relaciones:&lt;br /&gt;
  · rel_comp_def: r O s ≡ {(x,z). ∃y. (x, y) ∈ r ∧ (y, z) ∈ s}&lt;br /&gt;
&lt;br /&gt;
  Propiedades:&lt;br /&gt;
  · R_O_Id:        R O Id = R&lt;br /&gt;
  · rel_comp_mono: ⟦r&amp;#039; ⊆ r; s&amp;#039; ⊆ s⟧ ⟹ (r&amp;#039; O s&amp;#039;) ⊆ (r O s)&lt;br /&gt;
&lt;br /&gt;
  Imagen inversa de una relación:&lt;br /&gt;
  · converse_iff: ((a,b) ∈ r^-1) = ((b,a) ∈ r)&lt;br /&gt;
&lt;br /&gt;
  Propiedad de la imagen inversa de una relación:&lt;br /&gt;
  · converse_rel_comp: (r O s)^-1 = s^-1 O r^-1&lt;br /&gt;
&lt;br /&gt;
  Imagen de un conjunto mediante una relación:&lt;br /&gt;
  · Image_iff: (b ∈ r``A) = (∃x:A. (x, b) ∈ r)&lt;br /&gt;
&lt;br /&gt;
  Dominio de una relación:&lt;br /&gt;
  · Domain_iff: (a ∈ Domain r) = (∃y. (a, y) ∈ r)&lt;br /&gt;
&lt;br /&gt;
  Rango de una relación:&lt;br /&gt;
  · Range_iff: (a ∈ Range r) = (∃y. (y,a) ∈ r)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Definiciones_inductivas&amp;diff=659</id>
		<title>Definiciones inductivas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Definiciones_inductivas&amp;diff=659"/>
		<updated>2019-05-04T07:49:31Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 9: Definiciones inductivas *}&lt;br /&gt;
&lt;br /&gt;
theory T9_Definiciones_inductivas&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section {* El conjunto de los números pares *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  · El conjunto de los números pares se define inductivamente como el&lt;br /&gt;
    menor conjunto que contiene al 0 y es cerrado por la operación (+2).&lt;br /&gt;
&lt;br /&gt;
  · El conjunto de los números pares también puede definirse como los &lt;br /&gt;
    naturales divisible por 2.&lt;br /&gt;
&lt;br /&gt;
  · Veremos cómo se escriben las dos definiciones en Isabelle/HOL y cómo&lt;br /&gt;
    se demuestra su equivalencia.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definición inductiva del conjunto de los pares *}&lt;br /&gt;
&lt;br /&gt;
inductive_set par :: &amp;quot;nat set&amp;quot; where&lt;br /&gt;
  cero [intro!]: &amp;quot;0 ∈ par&amp;quot; &lt;br /&gt;
| paso [intro!]: &amp;quot;n ∈ par ⟹ (Suc (Suc n)) ∈ par&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  · Una definición inductiva está formada con reglas de introducción.&lt;br /&gt;
&lt;br /&gt;
  · La definición inductiva genera varios teoremas:&lt;br /&gt;
    · par.cero:   0 ∈ par&lt;br /&gt;
    · par.paso:   n ∈ par ⟹ Suc (Suc n) ∈ par&lt;br /&gt;
    · par.simps:  (a ∈ par) = (a = 0 ∨ (∃n. a = Suc (Suc n) ∧ n ∈ par))&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Uso de las reglas de introducción *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema: Los números de la forma 2*k son pares.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma dobles_son_pares [intro!]: &lt;br /&gt;
  &amp;quot;2*k ∈ par&amp;quot;&lt;br /&gt;
  apply (induct k) &lt;br /&gt;
     (* 1. 2 * 0 ∈ par&lt;br /&gt;
        2. ⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par *)&lt;br /&gt;
   apply auto&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma dobles_son_pares_2: &lt;br /&gt;
  &amp;quot;2*k ∈ par&amp;quot;&lt;br /&gt;
  by (induct k) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma dobles_son_pares_3:&lt;br /&gt;
  &amp;quot;2*k ∈ par&amp;quot;&lt;br /&gt;
proof (induct k)&lt;br /&gt;
  show &amp;quot;2 * 0 ∈ par&amp;quot; by auto&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par&amp;quot; by auto&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  · Nota: Nuestro objetivo es demostrar la equivalencia de la definición&lt;br /&gt;
    anterior y la definición mediante divisibilidad (even).&lt;br /&gt;
  &lt;br /&gt;
  · Lema: Si n es divisible por 2, entonces es par.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma even_imp_par: &amp;quot;even n ⟹ n ∈ par&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
subsection {* Regla de inducción *} &lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Entre las reglas generadas por la definión de par está la de&lt;br /&gt;
  inducción:&lt;br /&gt;
  · par.induct: ⟦ x ∈ par; &lt;br /&gt;
                 P 0; &lt;br /&gt;
                 ⋀n. ⟦n ∈ par; P n⟧ ⟹ P (Suc (Suc n))⟧ &lt;br /&gt;
                ⟹ P x&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema: Los números pares son divisibles por 2.&lt;br /&gt;
*} &lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma par_imp_even: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
  apply (induction rule: par.induct)&lt;br /&gt;
     (* 1. even 0&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply (simp only: dvd_def)&lt;br /&gt;
     (* 1. ∃k. 0 = 2 * k&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply (rule_tac x=0 in exI)&lt;br /&gt;
     (* 1. 0 = 2 * 0&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply simp&lt;br /&gt;
     (* ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
  apply (simp only: dvd_def)&lt;br /&gt;
     (* ⋀n. ⟦n ∈ par; ∃k. n = 2 * k⟧ ⟹ ∃k. Suc (Suc n) = 2 * k *)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
     (* ⋀n k. ⟦n ∈ par; n = 2 * k⟧ ⟹ ∃k. Suc (Suc n) = 2 * k*)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;k+1&amp;quot; in exI)&lt;br /&gt;
     (* ⋀n k. ⟦n ∈ par; n = 2 * k⟧ ⟹ Suc (Suc n) = 2 * (k + 1) *)&lt;br /&gt;
  apply simp&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración aplicativa›&lt;br /&gt;
lemma par_imp_even_2: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
  apply (induction rule: par.induct)&lt;br /&gt;
     (* 1. even 0&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma par_imp_even_3: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
  by (induction rule:par.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma par_imp_even_4: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
proof (induction rule: par.induct)&lt;br /&gt;
  show &amp;quot;even 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n::nat&lt;br /&gt;
  assume H1: &amp;quot;n ∈ par&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even n&amp;quot;&lt;br /&gt;
  have &amp;quot;∃k. n = 2*k&amp;quot; using H2 by (simp add: dvd_def)&lt;br /&gt;
  then obtain k where &amp;quot;n = 2*k&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;Suc (Suc n) = 2*(k+1)&amp;quot; by simp&lt;br /&gt;
  then have &amp;quot;∃k. Suc (Suc n) = 2*k&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;even (Suc (Suc n))&amp;quot; by (simp add: dvd_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹2ª demostración declarativa›&lt;br /&gt;
lemma par_imp_even_5: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ even n&amp;quot;&lt;br /&gt;
proof (induction rule: par.induct)&lt;br /&gt;
  show &amp;quot;even 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n::nat&lt;br /&gt;
  assume H1: &amp;quot;n ∈ par&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even n&amp;quot;&lt;br /&gt;
  then show &amp;quot;even (Suc (Suc n))&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema: Un número n es par syss es divisible por 2. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
theorem par_iff_even: &amp;quot;(n ∈ par) = (even n)&amp;quot;&lt;br /&gt;
  by (blast intro: even_imp_par par_imp_even)&lt;br /&gt;
&lt;br /&gt;
subsection{* Generalización y regla de inducción *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  · Antes de aplicar inducción se debe de generalizar la fórmula a&lt;br /&gt;
    probar.&lt;br /&gt;
 &lt;br /&gt;
  · Vamos a ilustrar el principio anterior en el caso de los conjuntos&lt;br /&gt;
    inductivamente definidos, con el siguiente ejemplo: si n+2 es par,&lt;br /&gt;
    entonces n también lo es.&lt;br /&gt;
&lt;br /&gt;
  · El siguiente intento falla:&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;Suc (Suc n) ∈ par ⟹ n ∈ par&amp;quot;&lt;br /&gt;
  apply (erule par.induct) &lt;br /&gt;
    (* 1. n ∈ par&lt;br /&gt;
       2. ⋀na. ⟦na ∈ par; n ∈ par⟧ ⟹ n ∈ par *)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En el intento anterior, los subobjetivos generados son&lt;br /&gt;
     1. n ∈ par&lt;br /&gt;
     2. ⋀na. ⟦na ∈ par; n ∈ par⟧ ⟹ n ∈ par&lt;br /&gt;
  que no se pueden demostrar.&lt;br /&gt;
&lt;br /&gt;
  Se ha perdido la información sobre Suc (Suc n).&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Reformulación del lema: Si n es par, entonces n-2 también lo es.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma par_imp_par_menos: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ n - 2 ∈ par&amp;quot;&lt;br /&gt;
  apply (induction rule: par.induct) &lt;br /&gt;
     (* 1. 0 - 2 ∈ par&lt;br /&gt;
        2. ⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par *)&lt;br /&gt;
   apply auto&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma par_imp_par_menos_2: &lt;br /&gt;
  &amp;quot;n ∈ par ⟹ n - 2 ∈ par&amp;quot;&lt;br /&gt;
  by (induction rule: par.induct) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;n ∈  par ⟹ n - 2 ∈ par&amp;quot;&lt;br /&gt;
proof (induction rule:par.induct)&lt;br /&gt;
  show &amp;quot;0 - 2 ∈ par&amp;quot; by auto&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par&amp;quot; by auto&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Con el lema anterior se puede demostrar el original.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &lt;br /&gt;
  &amp;quot;Suc (Suc n) ∈ par ⟹ n ∈ par&amp;quot;&lt;br /&gt;
  apply (drule par_imp_par_menos_2)&lt;br /&gt;
    (* Suc (Suc n) - 2 ∈ par ⟹ n ∈ par *)&lt;br /&gt;
  apply simp&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma Suc_Suc_par_imp_par: &lt;br /&gt;
  &amp;quot;Suc (Suc n) ∈ par ⟹ n ∈ par&amp;quot;&lt;br /&gt;
  by (drule par_imp_par_menos_2, simp)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma&lt;br /&gt;
  assumes &amp;quot;Suc (Suc n) ∈ par&amp;quot; &lt;br /&gt;
  shows   &amp;quot;n ∈ par&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;Suc (Suc n) - 2 ∈ par&amp;quot; &lt;br /&gt;
    using assms by (rule par_imp_par_menos_2)&lt;br /&gt;
  then show &amp;quot;n ∈ par&amp;quot; by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lemma. Un número natural n es par syss n+2 es par.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma [iff]: &amp;quot;((Suc (Suc n)) ∈ par) = (n ∈ par)&amp;quot;&lt;br /&gt;
  by (blast dest: Suc_Suc_par_imp_par)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se usa el atributo &amp;quot;iff&amp;quot; porque sirve como regla de simplificación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Definiciones mutuamente inductivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Definición cruzada de los conjuntos inductivos de los pares y de los &lt;br /&gt;
  impares:&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
inductive_set&lt;br /&gt;
  Pares    :: &amp;quot;nat set&amp;quot; and&lt;br /&gt;
  Impares  :: &amp;quot;nat set&amp;quot;&lt;br /&gt;
where&lt;br /&gt;
  ceroP:    &amp;quot;0 ∈ Pares&amp;quot;&lt;br /&gt;
| ParesI:   &amp;quot;n ∈ Impares ⟹ Suc n ∈ Pares&amp;quot;&lt;br /&gt;
| ImparesI: &amp;quot;n ∈ Pares   ⟹ Suc n ∈ Impares&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El esquema de inducción generado por la definición anterior es&lt;br /&gt;
  · Pares_Impares.induct:&lt;br /&gt;
    ⟦P1 0; &lt;br /&gt;
     ⋀n. ⟦n ∈ Impares; P2 n⟧ ⟹ P1 (Suc n);&lt;br /&gt;
     ⋀n. ⟦n ∈ Pares;   P1 n⟧ ⟹ P2 (Suc n)⟧&lt;br /&gt;
    ⟹ (x1 ∈ Pares ⟶ P1 x1) ∧ (x2 ∈ Impares ⟶ P2 x2)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración usando el esquema anterior.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))&amp;quot;&lt;br /&gt;
  apply (induction rule: Pares_Impares.induct)&lt;br /&gt;
      (* 1. even 0&lt;br /&gt;
         2. ⋀n. ⟦n ∈ Impares; even (Suc n)⟧ ⟹ even (Suc n)&lt;br /&gt;
         3. ⋀n. ⟦n ∈ Pares; even n⟧ ⟹ even (Suc (Suc n))*)&lt;br /&gt;
    apply auto&lt;br /&gt;
      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))&amp;quot;&lt;br /&gt;
  by (induction rule: Pares_Impares.induct) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración declarativa es›&lt;br /&gt;
lemma &amp;quot;(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))&amp;quot;&lt;br /&gt;
proof (induction rule:Pares_Impares.induct)&lt;br /&gt;
  show &amp;quot;even (0::nat)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  assume H1: &amp;quot;n ∈ Impares&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even (Suc n)&amp;quot;&lt;br /&gt;
  show &amp;quot;even (Suc n)&amp;quot; using H2 by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  assume H1: &amp;quot;n ∈ Pares&amp;quot; and&lt;br /&gt;
         H2: &amp;quot;even n&amp;quot;&lt;br /&gt;
  have &amp;quot;∃k. n = 2*k&amp;quot; using H2 by (simp add: dvd_def)&lt;br /&gt;
  then obtain k where &amp;quot;n = 2*k&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;Suc (Suc n) = 2*(k+1)&amp;quot; by auto&lt;br /&gt;
  then have &amp;quot;∃k. Suc (Suc n) = 2*k&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;even (Suc (Suc n))&amp;quot; by (simp add: dvd_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection {* Definición inductiva de predicados *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Definición inductiva del predicado es_par tal que (es_par n) se&lt;br /&gt;
  verifica si n es par.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
inductive es_par :: &amp;quot;nat ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;es_par 0&amp;quot; &lt;br /&gt;
| &amp;quot;es_par n ⟹ es_par (Suc(Suc n))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Heurística para elegir entre definir conjuntos o predicados:&lt;br /&gt;
  · si se va a combinar con operaciones conjuntistas, definir conjunto;&lt;br /&gt;
  · en caso contrario, definir predicado.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=658</id>
		<title>Razonamiento sobre árboles y bosques</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_%C3%A1rboles_y_bosques&amp;diff=658"/>
		<updated>2019-05-04T07:00:19Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 8: Razonamiento sobre árboles *}&lt;br /&gt;
&lt;br /&gt;
theory T8_Razonamiento_sobre_arboles&lt;br /&gt;
imports Main HOL.Parity&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En este tema se estudia razonamiento sobre otras estructuras&lt;br /&gt;
  recursivas como árboles binarios, árboles generales y bosques.&lt;br /&gt;
  &lt;br /&gt;
  También se muestra cómo definir tipos de datos por recursión cruzada y&lt;br /&gt;
  la demostración de sus propiedades por inducción.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento sobre árboles binarios *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de definición de tipos recursivos:&lt;br /&gt;
  Definir un tipo de dato para los árboles binarios.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbolB = Hoja &amp;quot;&amp;#039;a&amp;quot; &lt;br /&gt;
                   | Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot; &amp;quot;&amp;#039;a arbolB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de definición sobre árboles binarios:&lt;br /&gt;
  Definir la función &amp;quot;espejo&amp;quot; que aplicada a un árbol devuelve su imagen&lt;br /&gt;
  especular.  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun espejo :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a arbolB&amp;quot; where&lt;br /&gt;
  &amp;quot;espejo (Hoja x)     = (Hoja x)&amp;quot;&lt;br /&gt;
| &amp;quot;espejo (Nodo x i d) = (Nodo x (espejo d) (espejo i))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;espejo (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      Nodo a (Hoja e) (Nodo b (Hoja d) (Hoja c))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de demostración sobre árboles binarios:&lt;br /&gt;
  Demostrar que la función &amp;quot;espejo&amp;quot; es involutiva; es decir, para&lt;br /&gt;
  cualquier árbol a, se tiene que &lt;br /&gt;
     espejo (espejo a) = a.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma espejo_involutiva: &lt;br /&gt;
  &amp;quot;espejo (espejo a ) = a&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
     (* 1. ⋀x. espejo (espejo (Hoja x)) = Hoja x&lt;br /&gt;
        2. ⋀x1a a1 a2. &lt;br /&gt;
             ⟦espejo (espejo a1) = a1;&lt;br /&gt;
              espejo (espejo a2) = a2⟧&lt;br /&gt;
             ⟹ espejo (espejo (Nodo x1a a1 a2)) = Nodo x1a a1 a2 *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma espejo_involutiva_2: &lt;br /&gt;
  &amp;quot;espejo (espejo a ) = a&amp;quot;&lt;br /&gt;
  by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma espejo_involutiva_3:&lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot; &lt;br /&gt;
  shows &amp;quot;espejo (espejo a) = a&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x &lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot; by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x&lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;espejo (espejo (Nodo x i d)) = &lt;br /&gt;
          espejo (Nodo x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x (espejo (espejo i)) (espejo (espejo d))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = Nodo x i d&amp;quot; using h1 h2 by simp &lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
 qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;) es una abreviatura de &amp;quot;sea a1 un árbol binario&lt;br /&gt;
    cuyos elementos son de tipo b&amp;quot;. &lt;br /&gt;
  · (induct a) indica que el método de demostración es por inducción&lt;br /&gt;
    en el árbol binario a.&lt;br /&gt;
  · Se generan dos casos:&lt;br /&gt;
    1. ⋀a. espejo (espejo (Hoja a)) = Hoja a&lt;br /&gt;
    2. ⋀a1 a2 a3. ⟦espejo (espejo a2) = a2; &lt;br /&gt;
                   espejo (espejo a3) = a3⟧&lt;br /&gt;
                  ⟹ espejo (espejo (Nodo a1 a2 a3)) = Nodo a1 a2 a3&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo. [Aplanamiento de árboles]&lt;br /&gt;
  Definir la función &amp;quot;aplana&amp;quot; que aplane los árboles recorriéndolos en&lt;br /&gt;
  orden infijo.  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun aplana :: &amp;quot;&amp;#039;a arbolB ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana (Hoja x)     = [x]&amp;quot;&lt;br /&gt;
| &amp;quot;aplana (Nodo x i d) = (aplana i) @ [x] @ (aplana d)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;aplana (Nodo a (Nodo b (Hoja c) (Hoja d)) (Hoja e)) = &lt;br /&gt;
      [c, b, d, a, e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo. [Aplanamiento de la imagen especular] Demostrar que&lt;br /&gt;
     aplana (espejo a) = rev (aplana a)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  apply (induct a)&lt;br /&gt;
     (* 1. ⋀x. aplana (espejo (Hoja x)) = rev (aplana (Hoja x))&lt;br /&gt;
        2. ⋀x1a a1 a2.&lt;br /&gt;
             ⟦aplana (espejo a1) = rev (aplana a1);&lt;br /&gt;
              aplana (espejo a2) = rev (aplana a2)⟧&lt;br /&gt;
             ⟹ aplana (espejo (Nodo x1a a1 a2)) =&lt;br /&gt;
                 rev (aplana (Nodo x1a a1 a2)) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot;&lt;br /&gt;
  by (induct a) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes a :: &amp;quot;&amp;#039;b arbolB&amp;quot;&lt;br /&gt;
  shows &amp;quot;aplana (espejo a) = rev (aplana a)&amp;quot; (is &amp;quot;?P a&amp;quot;)&lt;br /&gt;
proof (induct a)&lt;br /&gt;
  fix x&lt;br /&gt;
  show &amp;quot;?P (Hoja x)&amp;quot; by simp &lt;br /&gt;
next&lt;br /&gt;
  fix x &lt;br /&gt;
  fix i assume h1: &amp;quot;?P i&amp;quot;&lt;br /&gt;
  fix d assume h2: &amp;quot;?P d&amp;quot;&lt;br /&gt;
  show &amp;quot;?P (Nodo x i d)&amp;quot; &lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;aplana (espejo (Nodo x i d)) = &lt;br /&gt;
          aplana (Nodo x (espejo d) (espejo i))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = (aplana (espejo d)) @ [x] @ (aplana (espejo i))&amp;quot; &lt;br /&gt;
      by simp&lt;br /&gt;
    also have &amp;quot;… = (rev (aplana d)) @ [x] @ (rev (aplana i))&amp;quot; &lt;br /&gt;
      using h1 h2 by simp&lt;br /&gt;
    also have &amp;quot;… = rev ((aplana i) @ [x] @ (aplana d))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = rev (aplana (Nodo x i d))&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
 qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Árboles y bosques. Recursión mutua e inducción *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. [Ejemplo de definición de tipos mediante recursión cruzada]&lt;br /&gt;
  · Un árbol de tipo a es una hoja o un nodo de tipo a junto con un&lt;br /&gt;
    bosque de tipo a.&lt;br /&gt;
  · Un bosque de tipo a es el boque vacío o un bosque contruido añadiendo&lt;br /&gt;
    un árbol de tipo a a un bosque de tipo a.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = Hoja | Nodo &amp;quot;&amp;#039;a&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
     and &amp;#039;a bosque = Vacio | ConsB &amp;quot;&amp;#039;a arbol&amp;quot; &amp;quot;&amp;#039;a bosque&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Regla de inducción correspondiente a la recursión cruzada:&lt;br /&gt;
  La regla de inducción sobre árboles y bosques es arbol_bosque.induct:&lt;br /&gt;
     ⟦P1 Hoja; &lt;br /&gt;
      ⋀x b. P2 b ⟹ P1 (Nodo x b); &lt;br /&gt;
      P2 Vacio;&lt;br /&gt;
      ⋀a b. ⟦P1 a; P2 b⟧ ⟹ P2 (ConsB a b)⟧ &lt;br /&gt;
     ⟹ P1 a ∧ P2 b&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplos de definición por recursión cruzada:&lt;br /&gt;
  · aplana_arbol a) es la lista obtenida aplanando el árbol a.   &lt;br /&gt;
  · (aplana_bosque b) es la lista obtenida aplanando el bosque b.   &lt;br /&gt;
  · (map_arbol f a) es el árbol obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del árbol a.   &lt;br /&gt;
  · (map_bosque f b) es el bosque obtenido aplicando la función f a&lt;br /&gt;
    todos los nodos del bosque b. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun aplana_arbol :: &amp;quot;&amp;#039;a arbol ⇒ &amp;#039;a list&amp;quot; and &lt;br /&gt;
    aplana_bosque :: &amp;quot;&amp;#039;a bosque ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;aplana_arbol Hoja         = []&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_arbol (Nodo x b)   = x # (aplana_bosque b)&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque Vacio       = []&amp;quot;&lt;br /&gt;
| &amp;quot;aplana_bosque (ConsB a b) = (aplana_arbol a) @ (aplana_bosque b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun map_arbol :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a arbol ⇒ &amp;#039;b arbol&amp;quot; and&lt;br /&gt;
    map_bosque :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a bosque ⇒ &amp;#039;b bosque&amp;quot; where&lt;br /&gt;
  &amp;quot;map_arbol  f Hoja        = Hoja&amp;quot;&lt;br /&gt;
| &amp;quot;map_arbol  f (Nodo x b)  = Nodo (f x) (map_bosque f b)&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f Vacio       = Vacio&amp;quot;&lt;br /&gt;
| &amp;quot;map_bosque f (ConsB a b) = ConsB (map_arbol f a) (map_bosque f b)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por inducción cruzada:&lt;br /&gt;
  Demostrar que:&lt;br /&gt;
  · aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
  · aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
declare [[names_short]]&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  apply (induct_tac a and b)&lt;br /&gt;
       (*  1. aplana_arbol (map_arbol f Hoja) =&lt;br /&gt;
              map f (aplana_arbol Hoja)&lt;br /&gt;
           2. ⋀x1 x2.&lt;br /&gt;
                aplana_bosque (map_bosque f x2) =&lt;br /&gt;
                map f (aplana_bosque x2) ⟹&lt;br /&gt;
                aplana_arbol (map_arbol f (Nodo x1 x2)) =&lt;br /&gt;
                map f (aplana_arbol (Nodo x1 x2))&lt;br /&gt;
           3. aplana_bosque (map_bosque f Vacio) =&lt;br /&gt;
              map f (aplana_bosque Vacio)&lt;br /&gt;
           4. ⋀x1 x2.&lt;br /&gt;
                ⟦aplana_arbol (map_arbol f x1) = map f (aplana_arbol x1);&lt;br /&gt;
                 aplana_bosque (map_bosque f x2) = map f (aplana_bosque x2)⟧&lt;br /&gt;
                ⟹ aplana_bosque (map_bosque f (ConsB x1 x2)) =&lt;br /&gt;
                    map f (aplana_bosque (ConsB x1 x2)) *)&lt;br /&gt;
     apply simp_all&lt;br /&gt;
       (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  by (induct_tac a and b) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;aplana_arbol  (map_arbol  f a) = map f (aplana_arbol a)&lt;br /&gt;
     ∧ aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
proof (induct_tac a and b)&lt;br /&gt;
  show &amp;quot;aplana_arbol (map_arbol f Hoja ) = map f (aplana_arbol Hoja)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x b&lt;br /&gt;
  assume HI: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_arbol (map_arbol f (Nodo x b)) = &lt;br /&gt;
        aplana_arbol (Nodo (f x) (map_bosque f b))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (aplana_bosque (map_bosque f b))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = (f x) # (map f (aplana_bosque b))&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_arbol (Nodo x b))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;aplana_arbol (map_arbol f (Nodo x b))&lt;br /&gt;
                = map f (aplana_arbol (Nodo x b))&amp;quot; .&lt;br /&gt;
next&lt;br /&gt;
  show &amp;quot;aplana_bosque (map_bosque f Vacio) = map f (aplana_bosque Vacio)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a b&lt;br /&gt;
  assume HI1: &amp;quot;aplana_arbol (map_arbol f a) = map f (aplana_arbol a)&amp;quot;&lt;br /&gt;
     and HI2: &amp;quot;aplana_bosque (map_bosque f b) = map f (aplana_bosque b)&amp;quot;&lt;br /&gt;
  have &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) = &lt;br /&gt;
        aplana_bosque (ConsB (map_arbol f a) (map_bosque f b))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = aplana_arbol (map_arbol f a) @ &lt;br /&gt;
                  aplana_bosque (map_bosque f b)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (map f (aplana_arbol a)) @ (map f (aplana_bosque b))&amp;quot; &lt;br /&gt;
    using HI1 HI2 by simp&lt;br /&gt;
  also have &amp;quot;… = map f (aplana_bosque (ConsB a b))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;aplana_bosque (map_bosque f (ConsB a b)) &lt;br /&gt;
                = map f (aplana_bosque (ConsB a b))&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct_tac a and b) indica que el método de demostración es por&lt;br /&gt;
    inducción cruzada sobre a y b.&lt;br /&gt;
  · Se generan 4 casos:&lt;br /&gt;
    1. aplana_arbol (map_arbol arbol.Hoja h) = map h (aplana_arbol arbol.Hoja)&lt;br /&gt;
    2. ⋀a bosque.&lt;br /&gt;
          aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque) ⟹&lt;br /&gt;
          aplana_arbol (map_arbol (arbol.Nodo a bosque) h) =&lt;br /&gt;
          map h (aplana_arbol (arbol.Nodo a bosque))&lt;br /&gt;
    3. aplana_bosque (map_bosque Vacio h) = map h (aplana_bosque Vacio)&lt;br /&gt;
    4. ⋀arbol bosque.&lt;br /&gt;
          ⟦aplana_arbol (map_arbol arbol h) = map h (aplana_arbol arbol);&lt;br /&gt;
           aplana_bosque (map_bosque bosque h) = map h (aplana_bosque bosque)⟧&lt;br /&gt;
          ⟹ aplana_bosque (map_bosque (ConsB arbol bosque) h) =&lt;br /&gt;
             map h (aplana_bosque (ConsB arbol bosque))&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_por_casos_y_por_inducci%C2%A2n&amp;diff=627</id>
		<title>Razonamiento por casos y por inducci¢n</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_por_casos_y_por_inducci%C2%A2n&amp;diff=627"/>
		<updated>2019-05-02T08:22:35Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 7: Razonamiento por casos y por inducción *}&lt;br /&gt;
&lt;br /&gt;
theory T7_Razonamiento_por_casos_y_por_induccion&lt;br /&gt;
imports Main HOL.Parity&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En este tema se amplían los métodos de demostración por casos y por&lt;br /&gt;
  inducción iniciados en el tema anterior.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por distinción de casos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Distinción de casos booleanos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por distinción de casos booleanos:&lt;br /&gt;
  Demostrar &amp;quot;¬A ∨ A&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply cases           (* 1. ?P ⟹ ¬ A ∨ A&lt;br /&gt;
                           2. ¬ ?P ⟹ ¬ A ∨ A  *)&lt;br /&gt;
   apply (erule disjI2) (* 1. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
  apply (erule disjI1)  (* No subgoals! *)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply cases     (* 1. ?P ⟹ ¬ A ∨ A&lt;br /&gt;
                     2. ¬ ?P ⟹ ¬ A ∨ A  *)&lt;br /&gt;
   apply simp_all (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
proof cases&lt;br /&gt;
  assume &amp;quot;A&amp;quot; &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;¬A&amp;quot; &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios de la demostración anterior:&lt;br /&gt;
  · &amp;quot;proof cases&amp;quot; indica que el método de demostración será por&lt;br /&gt;
    distinción de casos. &lt;br /&gt;
  · Se generan 2 casos:&lt;br /&gt;
       1. ?P ⟹ ¬A ∨ A&lt;br /&gt;
       2. ¬?P ⟹ ¬A ∨ A&lt;br /&gt;
    donde ?P es una variable sobre las fórmulas.&lt;br /&gt;
  · (assume &amp;quot;A&amp;quot;) indica que se está usando &amp;quot;A&amp;quot; en lugar de la variable&lt;br /&gt;
    ?P.&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica usando la fórmula anterior.&lt;br /&gt;
  · &amp;quot;..&amp;quot; indica usando la regla lógica necesaria (las reglas lógicas se&lt;br /&gt;
    estudiarán en los siguientes temas).&lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente caso (se puede observar cómo ha&lt;br /&gt;
    sustituido ¬?P por ¬A.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por distinción de casos booleanos con nombres: &lt;br /&gt;
  Demostrar &amp;quot;¬A ∨ A&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply (cases &amp;quot;A&amp;quot;)     (* 1. A ⟹ ¬ A ∨ A&lt;br /&gt;
                           2. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
   apply (erule disjI2) (* 1. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
  apply (erule disjI1)  (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply (cases &amp;quot;A&amp;quot;)     (* 1. A ⟹ ¬ A ∨ A&lt;br /&gt;
                           2. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
   apply simp_all       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
proof (cases &amp;quot;A&amp;quot;)&lt;br /&gt;
  case True &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  case False &lt;br /&gt;
  thus &amp;quot;¬A ∨ A&amp;quot; .. &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (cases &amp;quot;A&amp;quot;) indica que la demostración se hará por casos según los&lt;br /&gt;
    distintos valores de &amp;quot;A&amp;quot;.&lt;br /&gt;
  · Como &amp;quot;A&amp;quot; es una fórmula, sus posibles valores son verdadero o falso.&lt;br /&gt;
  · &amp;quot;case True&amp;quot; indica que se está suponiendo que A es verdadera. Es&lt;br /&gt;
    equivalente a &amp;quot;assume A&amp;quot;.&lt;br /&gt;
  · &amp;quot;case False&amp;quot; indica que se está suponiendo que A es falsa. Es&lt;br /&gt;
    equivalente a &amp;quot;assume ¬A&amp;quot;.&lt;br /&gt;
  · En general, &lt;br /&gt;
    · el método (cases F) es una abreviatura de la aplicación de la regla&lt;br /&gt;
         ⟦F ⟹ Q; ¬F ⟹ Q⟧ ⟹ Q  &lt;br /&gt;
    · La expresión &amp;quot;case True&amp;quot; es una abreviatura de F.&lt;br /&gt;
    · La expresión &amp;quot;case False&amp;quot; es una abreviatura de ¬F.&lt;br /&gt;
  · Ventajas de &amp;quot;cases&amp;quot; con nombre: &lt;br /&gt;
    · reduce la escritura de la fórmula y&lt;br /&gt;
    · es independiente del orden de los casos.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Distinción de casos sobre otros tipos de datos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de distinción de casos sobre listas: &lt;br /&gt;
  Demostrar que la longitud del resto de una lista es la longitud de la&lt;br /&gt;
  lista menos 1. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  apply (cases xs)&lt;br /&gt;
     (*  1. xs = [] ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
         2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                     length (tl xs) = length xs - 1*)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;length (tl xs) = length xs - 1&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;length(tl xs) = length xs - 1&amp;quot; by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; indica que la demostración se hará por casos sobre los&lt;br /&gt;
    posibles valores de xs.&lt;br /&gt;
  · Como xs es una lista, sus posibles valores son la lista vacía ([]) o&lt;br /&gt;
    una lista no vacía (de la forma (y#ys)).&lt;br /&gt;
  · Se generan 2 casos:&lt;br /&gt;
       1. xs = [] ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
       2. ⋀a list. xs = a # list ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración simplificada es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons &lt;br /&gt;
  then show ?thesis by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &lt;br /&gt;
       &amp;quot;assume xs =[]&amp;quot;.&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &lt;br /&gt;
       &amp;quot;fix y ys assume xs = y#ys&amp;quot;&lt;br /&gt;
  · ?thesis es una abreviatura de la conclusión del lema.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En el siguiente ejemplo vamos a demostrar una propiedad de la función&lt;br /&gt;
  drop que está definida en la teoría List de forma que (drop n xs) la&lt;br /&gt;
  lista obtenida eliminando en xs} los n primeros elementos. Su&lt;br /&gt;
  definición es la siguiente   &lt;br /&gt;
     drop_Nil:  &amp;quot;drop n []     = []&amp;quot; &lt;br /&gt;
     drop_Cons: &amp;quot;drop n (x#xs) = (case n of &lt;br /&gt;
                                    0 =&amp;gt; x#xs | &lt;br /&gt;
                                    Suc(m) =&amp;gt; drop m xs)&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de análisis de casos:&lt;br /&gt;
  Demostrar que el resultado de eliminar los n+1 primeros elementos de&lt;br /&gt;
  xs es el mismo que eliminar los n primeros elementos del resto de xs.  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es› &lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ drop (n + 1) xs = drop n (tl xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                     drop (n + 1) xs = drop n (tl xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
  by (cases xs) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Inducción matemática *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  [Principio de inducción matemática]&lt;br /&gt;
  Para demostrar una propiedad P para todos los números naturales basta&lt;br /&gt;
  probar que el 0 tiene la propiedad P y que si n tiene la propiedad P,&lt;br /&gt;
  entonces n+1 también la tiene. &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción matemática está formalizado en&lt;br /&gt;
  el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  Ejemplo de demostración por inducción: Usaremos el principio de&lt;br /&gt;
  inducción matemática para demostrar que &lt;br /&gt;
     1 + 3 + ... + (2n-1) = n^2&lt;br /&gt;
&lt;br /&gt;
  Definición. [Suma de los primeros impares] &lt;br /&gt;
  (suma_impares n) la suma de los n números impares. Por ejemplo,&lt;br /&gt;
     suma_impares 3  =  9&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun suma_impares :: &amp;quot;nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;suma_impares 0 = 0&amp;quot; &lt;br /&gt;
| &amp;quot;suma_impares (Suc n) = (2*(Suc n) - 1) + suma_impares n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;suma_impares 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por inducción matemática:&lt;br /&gt;
  Demostrar que la suma de los n primeros números impares es n^2.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  apply (induct n) &lt;br /&gt;
     (* 1. suma_impares 0 = 0 * 0&lt;br /&gt;
        2. ⋀n. suma_impares n = n * n ⟹&lt;br /&gt;
                suma_impares (Suc n) = Suc n * Suc n*) &lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *) &lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración del lema anterior por inducción y razonamiento &lt;br /&gt;
   ecuacional›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;suma_impares 0 = 0 * 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n assume HI: &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  have &amp;quot;suma_impares (Suc n) = (2 * (Suc n) - 1) + suma_impares n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (2 * (Suc n) - 1) + n * n&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;… = n * n + 2 * n + 1&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;suma_impares (Suc n) = (Suc n) * (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración del lema anterior con patrones y razonamiento &lt;br /&gt;
   ecuacional›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;?P 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume HI: &amp;quot;?P n&amp;quot;&lt;br /&gt;
  have &amp;quot;suma_impares (Suc n) = (2 * (Suc n) - 1) + suma_impares n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (2 * (Suc n) - 1) + n * n&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;… = n * n + 2 * n + 1&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;?P (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario sobre la demostración anterior:&lt;br /&gt;
  · Con la expresión&lt;br /&gt;
       &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
    se abrevia &amp;quot;suma_impares n = n * n&amp;quot; como &amp;quot;?P n&amp;quot;. Por tanto, &lt;br /&gt;
       &amp;quot;?P 0&amp;quot;       es una abreviatura de &amp;quot;suma_impares 0 = 0 * 0&amp;quot;&lt;br /&gt;
       &amp;quot;?P (Suc n)&amp;quot; es una abreviatura de &amp;quot;suma_impares (Suc n) = &lt;br /&gt;
                                           (Suc n) * (Suc n)&amp;quot;&lt;br /&gt;
  · En general, cualquier fórmula seguida de (is patrón) equipara el&lt;br /&gt;
    patrón con la fórmula. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración usando patrones es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;?P 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;?P n&amp;quot;&lt;br /&gt;
  then show &amp;quot;?P (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
  &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de definición con existenciales. &lt;br /&gt;
  Un número natural n es par si existe un natural m tal que n=m+m.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition par :: &amp;quot;nat ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;par n ≡ ∃m. n=m+m&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*                                &lt;br /&gt;
  Ejemplo de inducción y existenciales: &lt;br /&gt;
  Demostrar que para todo número natural n, se verifica que n*(n+1) par. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &lt;br /&gt;
  shows &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  apply (induct n)&lt;br /&gt;
     (* par (0 * (0 + 1))&lt;br /&gt;
        ⋀n. par (n * (n + 1)) ⟹ par (Suc n * (Suc n + 1)) *)&lt;br /&gt;
   apply (simp add: par_def)&lt;br /&gt;
     (* ⋀n. par (n * (n + 1)) ⟹ par (Suc n * (Suc n + 1)) *)&lt;br /&gt;
  apply (simp add: par_def)&lt;br /&gt;
     (* ⋀n. ∃m. n + n * n = m + m ⟹&lt;br /&gt;
             ∃m. Suc (Suc (n + (n + (n + n * n)))) = m + m *)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
     (* ⋀n m. n + n * n = m + m ⟹&lt;br /&gt;
              ∃m. Suc (Suc (n + (n + (n + n * n)))) = m + m*)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;m+n+1&amp;quot; in exI)&lt;br /&gt;
     (* ⋀n m. n + n * n = m + m ⟹&lt;br /&gt;
              Suc (Suc (n + (n + (n + n * n)))) =&lt;br /&gt;
              m + n + 1 + (m + n + 1)*)&lt;br /&gt;
  apply simp&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa con arith›&lt;br /&gt;
lemma &lt;br /&gt;
  shows &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  apply (induct n)&lt;br /&gt;
     (* par (0 * (0 + 1))&lt;br /&gt;
        ⋀n. par (n * (n + 1)) ⟹ par (Suc n * (Suc n + 1)) *)&lt;br /&gt;
   apply (simp add: par_def)&lt;br /&gt;
     (* ⋀n. par (n * (n + 1)) ⟹ par (Suc n * (Suc n + 1)) *)&lt;br /&gt;
  apply (simp add: par_def)&lt;br /&gt;
     (* ⋀n. ∃m. n + n * n = m + m ⟹&lt;br /&gt;
             ∃m. Suc (Suc (n + (n + (n + n * n)))) = m + m *)&lt;br /&gt;
  apply arith&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  by (induct n) (auto simp add: par_def, arith)&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;par (0*(0+1))&amp;quot; by (simp add: par_def)&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  then have &amp;quot;∃m. n*(n+1) = m+m&amp;quot; by (simp add:par_def)&lt;br /&gt;
  then obtain m where m: &amp;quot;n*(n+1) = m+m&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;(Suc n)*((Suc n)+1) = (m+n+1)+(m+n+1)&amp;quot; by auto&lt;br /&gt;
  then have &amp;quot;∃m. (Suc n)*((Suc n)+1) = m+m&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;par ((Suc n)*((Suc n)+1))&amp;quot; by (simp add:par_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (fixes n :: &amp;quot;nat&amp;quot;) es una abreviatura de &amp;quot;sea n un número natural&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En Isabelle puede demostrarse de manera más simple un lema equivalente&lt;br /&gt;
  usando en lugar de la función &amp;quot;par&amp;quot; la función &amp;quot;even&amp;quot; definida en la&lt;br /&gt;
  teoría Parity por&lt;br /&gt;
     even x ⟷ x mod 2 = 0&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;even (n*(n+1))&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · Para poder usar la función &amp;quot;even&amp;quot; de la librería Parity es necesario&lt;br /&gt;
    importar dicha librería. Por ello, antes del inicio de la teoría&lt;br /&gt;
    aparece &lt;br /&gt;
       imports Main HOL.Parity&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Para completar la demostración basta demostrar la equivalencia de las&lt;br /&gt;
  funciones &amp;quot;par&amp;quot; y &amp;quot;even&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &lt;br /&gt;
  shows &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
  apply (simp add: par_def)  (* (∃m. n = m + m) = even n *)&lt;br /&gt;
  apply presburger           (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &lt;br /&gt;
  shows &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
  by (simp add: par_def, presburger)&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;par n = (∃m. n = m+m)&amp;quot; by (simp add:par_def)&lt;br /&gt;
  then show &amp;quot;par n = even n&amp;quot; by presburger&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;by presburger&amp;quot; indica que se use como método de demostración el&lt;br /&gt;
    algoritmo de decisión de la aritmética de Presburger.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Inducción estructural *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Inducción estructural:&lt;br /&gt;
  · En Isabelle puede hacerse inducción estructural sobre cualquier tipo&lt;br /&gt;
    recursivo.&lt;br /&gt;
  · La inducción matemática es la inducción estructural sobre el tipo de&lt;br /&gt;
    los naturales.&lt;br /&gt;
  · El esquema de inducción estructural sobre listas es&lt;br /&gt;
    · list.induct: ⟦P []; ⋀x ys. P ys ⟹ P (x # ys)⟧ ⟹ P zs&lt;br /&gt;
  · Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
    que la lista vacía tiene la propiedad y que al añadir un elemento a una&lt;br /&gt;
    lista que tiene la propiedad se obtiene una lista que también tiene la&lt;br /&gt;
    propiedad. &lt;br /&gt;
  · En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
    mediante el teorema list.induct que puede verse con &lt;br /&gt;
       thm list.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Concatenación de listas:&lt;br /&gt;
  En la teoría List.thy está definida la concatenación de listas (que&lt;br /&gt;
  se representa por @) como sigue&lt;br /&gt;
     append_Nil:  &amp;quot;[]@ys     = ys&amp;quot;&lt;br /&gt;
     append_Cons: &amp;quot;(x#xs)@ys = x#(xs@ys)&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Ejemplo de inducción sobre listas]&lt;br /&gt;
  Demostrar que la concatenación de listas es asociativa.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma conc_asociativa: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
  apply (induct xs)&lt;br /&gt;
     (* 1. [] @ (ys @ zs) = ([] @ ys) @ zs&lt;br /&gt;
        2. ⋀a xs. xs @ (ys @ zs) = (xs @ ys) @ zs ⟹&lt;br /&gt;
                  (a # xs) @ (ys @ zs) = ((a # xs) @ ys) @ zs*)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma conc_asociativa_2: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma conc_asociativa_3: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;[] @ (ys @ zs) = ([] @ ys) @ zs&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;[] @ (ys @ zs) = ys @ zs&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = ([] @ ys) @ zs&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
  show &amp;quot;(x#xs) @ (ys @ zs) = ((x#xs) @ ys) @ zs&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(x#xs) @ (ys @ zs) = x#(xs @ (ys @ zs))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = x#((xs @ ys) @ zs)&amp;quot; using HI by simp&lt;br /&gt;
    also have &amp;quot;… = (x#(xs @ ys)) @ zs&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = ((x#xs) @ ys) @ zs&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Recursión general. La función de Ackermann *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  El objetivo de esta sección es mostrar el uso de las definiciones&lt;br /&gt;
  recursivas generales y sus esquemas de inducción. Como ejemplo se usa la&lt;br /&gt;
  función de Ackermann (se puede consultar información sobre dicha función en&lt;br /&gt;
  http://en.wikipedia.org/wiki/Ackermann_function).&lt;br /&gt;
&lt;br /&gt;
  Definición.  La función de Ackermann se define por&lt;br /&gt;
    A(m,n) = n+1,             si m=0,&lt;br /&gt;
             A(m-1,1),        si m&amp;gt;0 y n=0,&lt;br /&gt;
             A(m-1,A(m,n-1)), si m&amp;gt;0 y n&amp;gt;0&lt;br /&gt;
  para todo los números naturales. &lt;br /&gt;
&lt;br /&gt;
  La función de Ackermann es recursiva, pero no es primitiva recursiva. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun ack :: &amp;quot;nat ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;ack 0       n       = n+1&amp;quot; &lt;br /&gt;
| &amp;quot;ack (Suc m) 0       = ack m 1&amp;quot; &lt;br /&gt;
| &amp;quot;ack (Suc m) (Suc n) = ack m (ack (Suc m) n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
― ‹Ejemplo de evaluación›&lt;br /&gt;
value &amp;quot;ack 2 3&amp;quot; (* devuelve 9 *)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Esquema de inducción correspondiente a una función:&lt;br /&gt;
  · Al definir una función recursiva general se genera una regla de&lt;br /&gt;
    inducción. En la definición anterior, la regla generada es&lt;br /&gt;
    ack.induct: &lt;br /&gt;
       ⟦⋀n. P 0 n; &lt;br /&gt;
        ⋀m. P m 1 ⟹ P (Suc m) 0;&lt;br /&gt;
        ⋀m n. ⟦P (Suc m) n; P m (ack (Suc m) n)⟧ ⟹ P (Suc m) (Suc n)⟧&lt;br /&gt;
       ⟹ P a b&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por la inducción correspondiente a una función:&lt;br /&gt;
  Demostrar que para todos m y n, A(m,n) &amp;gt; n.&lt;br /&gt;
*} &lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
  apply (induct m n rule: ack.induct) &lt;br /&gt;
      (* 1. ⋀n. n &amp;lt; ack 0 n&lt;br /&gt;
         2. ⋀m. 1 &amp;lt; ack m 1 ⟹ 0 &amp;lt; ack (Suc m) 0&lt;br /&gt;
         3. ⋀m n. ⟦n &amp;lt; ack (Suc m) n;&lt;br /&gt;
                   ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)⟧&lt;br /&gt;
                  ⟹ Suc n &amp;lt; ack (Suc m) (Suc n) *)&lt;br /&gt;
    apply simp_all&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración automática›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
  by (induct m n rule: ack.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
proof (induct m n rule: ack.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;ack 0 n &amp;gt; n&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix m &lt;br /&gt;
  assume &amp;quot;ack m 1 &amp;gt; 1&amp;quot;&lt;br /&gt;
  then show &amp;quot;ack (Suc m) 0 &amp;gt; 0&amp;quot; by simp&lt;br /&gt;
next  &lt;br /&gt;
  fix m n&lt;br /&gt;
  assume &amp;quot;n &amp;lt; ack (Suc m) n&amp;quot; and &lt;br /&gt;
         &amp;quot;ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)&amp;quot;&lt;br /&gt;
  then show &amp;quot;Suc n &amp;lt; ack (Suc m) (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct m n rule: ack.induct) indica que el método de demostración&lt;br /&gt;
    es el esquema de recursión correspondiente a la definición de &lt;br /&gt;
    (ack m n).&lt;br /&gt;
  · Se generan 3 casos:&lt;br /&gt;
    1. ⋀n. n &amp;lt; ack 0 n&lt;br /&gt;
    2. ⋀m. 1 &amp;lt; ack m 1 ⟹ 0 &amp;lt; ack (Suc m) 0&lt;br /&gt;
    3. ⋀m n. ⟦n &amp;lt; ack (Suc m) n; &lt;br /&gt;
              ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)⟧&lt;br /&gt;
             ⟹ Suc n &amp;lt; ack (Suc m) (Suc n)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=625</id>
		<title>Razonamiento sobre programas en Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=625"/>
		<updated>2019-05-02T06:40:43Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 6: Razonamiento sobre programas *}&lt;br /&gt;
&lt;br /&gt;
theory T6_Razonamiento_sobre_programas&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  En este tema se demuestra con Isabelle las propiedades de los&lt;br /&gt;
  programas funcionales de tema 6 http://bit.ly/2Za6YWY&lt;br /&gt;
&lt;br /&gt;
  Para cada propiedades se presentan distintos tipos de demostraciones:&lt;br /&gt;
  automáticas, aplicativas y declarativas. *} &lt;br /&gt;
&lt;br /&gt;
declare [[names_short]]&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento ecuacional *}&lt;br /&gt;
&lt;br /&gt;
text {* ----------------------------------------------------------------&lt;br /&gt;
  Ejemplo 1. Definir, por recursión, la función&lt;br /&gt;
     longitud :: &amp;#039;a list ⇒ nat&lt;br /&gt;
  tal que (longitud xs) es la longitud de la listas xs. Por ejemplo,&lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
fun longitud :: &amp;quot;&amp;#039;a list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;longitud []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;longitud (x#xs) = 1 + longitud xs&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
value &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 2. Demostrar que &lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 3. Definir la función&lt;br /&gt;
     fun intercambia :: &amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&lt;br /&gt;
  tal que (intercambia p) es el par obtenido intercambiando las&lt;br /&gt;
  componentes del par p. Por ejemplo,&lt;br /&gt;
     intercambia (u,v) = (v,u)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun intercambia :: &amp;quot;&amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;intercambia (x,y) = (y,x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;intercambia (u,v) = (v,u)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La definición de la función intercambia genera una regla de&lt;br /&gt;
  simplificación&lt;br /&gt;
  · intercambia.simps: intercambia (x,y) = (y,x)&lt;br /&gt;
  &lt;br /&gt;
  Se puede ver con &lt;br /&gt;
  · thm intercambia.simps &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm intercambia.simps&lt;br /&gt;
(* da intercambia (?x, ?y) = (?y, ?x) *)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 4. (p.6) Demostrar que &lt;br /&gt;
     intercambia (intercambia (x,y)) = (x,y)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by (simp only: intercambia.simps)&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  apply (simp only: intercambia.simps)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  by simp&lt;br /&gt;
  also have &amp;quot;... = (x,y)&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  also have &amp;quot;... = (x,y)&amp;quot; &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;by (simp only: intercambia.simps)&amp;quot; para indicar que sólo se usa&lt;br /&gt;
    como regla de escritura la correspondiente a la definición de&lt;br /&gt;
    intercambia,&lt;br /&gt;
  · &amp;quot;also&amp;quot; para encadenar pasos ecuacionales,&lt;br /&gt;
  · &amp;quot;...&amp;quot; para representar la derecha de la igualdad anterior en un&lt;br /&gt;
    razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;finally&amp;quot; para indicar el último pasa de un razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.&lt;br /&gt;
  · &amp;quot;by simp&amp;quot; para indicar el método de demostración por simplificación y &lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas,&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota: La diferencia entre las dos demostraciones es que en los dos&lt;br /&gt;
  primeros pasos no se explicita la regla de simplificación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 5. Definir, por recursión, la función&lt;br /&gt;
     inversa :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversa xs) es la lista obtenida invirtiendo el orden de los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     inversa [a,d,c] = [c,d,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun inversa :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversa []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;inversa (x#xs) = inversa xs @ [x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversa [a,d,c] = [c,d,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 6. (p. 9) Demostrar que &lt;br /&gt;
     inversa [x] = [x]&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En la demostración anterior se usaron las siguientes reglas:&lt;br /&gt;
  · inversa.simps(1): inversa [] = []&lt;br /&gt;
  · inversa.simps(2): inversa (x#xs) = inversa xs @ [x]&lt;br /&gt;
  · append_Nil:       [] @ ys = ys&lt;br /&gt;
  Vamos a explicitar su aplicación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2)) (* inversa [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: inversa.simps(1)) (* [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: append_Nil)       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = (inversa []) @ [x]&amp;quot; by (simp only: inversa.simps(2))&lt;br /&gt;
  also have &amp;quot;... = [] @ [x]&amp;quot; by (simp only: inversa.simps(1))&lt;br /&gt;
  also have &amp;quot;... = [x]&amp;quot; by (simp only: append_Nil) &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = (inversa []) @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = [] @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = [x]&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por inducción sobre los naturales *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  [Principio de inducción sobre los naturales] Para demostrar una&lt;br /&gt;
  propiedad P para todos los números naturales basta probar que el 0&lt;br /&gt;
  tiene la propiedad P y que si n tiene la propiedad P, entonces n+1&lt;br /&gt;
  también la tiene.  &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre los naturales está&lt;br /&gt;
  formalizado en el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 7. Definir la función&lt;br /&gt;
     repite :: nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (repite n x) es la lista formada por n copias del elemento&lt;br /&gt;
  x. Por ejemplo, &lt;br /&gt;
     repite 3 a = [a,a,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;repite 0 x       = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) x = x # (repite n x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;repite 3 a = [a,a,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 8. (p. 18) Demostrar que &lt;br /&gt;
     longitud (repite n x) = n&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp      (* 1. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
  apply simp       (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa con simp_all es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp_all  (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (repite n x)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + n&amp;quot; using HI by simp&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · A la derecha de proof se indica el método de la demostración.&lt;br /&gt;
  · (induct n) indica que la demostración se hará por inducción en n.&lt;br /&gt;
  · Se generan dos subobjetivos correspondientes a la base y el paso de&lt;br /&gt;
    inducción:&lt;br /&gt;
    1. longitud (repite 0 x) = 0&lt;br /&gt;
    2. ⋀n. longitud (repite n x) = n ⟹ &lt;br /&gt;
            longitud (repite (Suc n) x) = Suc n&lt;br /&gt;
    donde ⋀n se lee &amp;quot;para todo n&amp;quot;.  &lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente subobjetivo.&lt;br /&gt;
  · &amp;quot;fix n&amp;quot; indica &amp;quot;sea n un número natural cualquiera&amp;quot;&lt;br /&gt;
  · assume HI: &amp;quot;longitud (repite n x) = n&amp;quot; indica «supongamos que &lt;br /&gt;
    &amp;quot;longitud (repite n x) = n&amp;quot; y sea HI la etiqueta de este supuesto».&lt;br /&gt;
  · &amp;quot;using HI&amp;quot; usando la propiedad etiquetada con HI. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por inducción sobre listas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
  que la lista vacía tiene la propiedad y que al añadir un elemento a&lt;br /&gt;
  una lista que tiene la propiedad se obtiene otra lista que también&lt;br /&gt;
  tiene la propiedad. &lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
  mediante el teorema list.induct &lt;br /&gt;
     ⟦P []; &lt;br /&gt;
      ⋀x xs. P xs ⟹ P (x#xs)⟧ &lt;br /&gt;
     ⟹ P xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 9. Definir la función&lt;br /&gt;
     conc :: &amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (conc xs ys) es la concatención de las listas xs e ys. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun conc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;conc []     ys = ys&amp;quot;&lt;br /&gt;
| &amp;quot;conc (x#xs) ys = x # (conc xs ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 10. (p. 24) Demostrar que &lt;br /&gt;
     conc xs (conc ys zs) = (conc xs ys) zs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  apply (induct xs) (*  1. conc [] (conc ys zs) = conc (conc [] ys) zs&lt;br /&gt;
                        2. ⋀a xs.&lt;br /&gt;
                              conc xs (conc ys zs) =&lt;br /&gt;
                              conc (conc xs ys) zs ⟹&lt;br /&gt;
                              conc (a # xs) (conc ys zs) =&lt;br /&gt;
                              conc (conc (a # xs) ys) zs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x # (conc (conc xs ys) zs)&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = conc (conc (x # xs) ys) zs&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 11. Refutar que &lt;br /&gt;
     conc xs ys = conc ys xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;conc xs ys = conc ys xs&amp;quot;&lt;br /&gt;
  quickcheck&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Encuentra el contraejemplo, &lt;br /&gt;
  xs = [a2]&lt;br /&gt;
  ys = [a1] *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 12. (p. 28) Demostrar que &lt;br /&gt;
     conc xs [] = xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. conc [] [] = []&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             conc xs [] = xs ⟹&lt;br /&gt;
                             conc (a # xs) [] = a # xs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x # xs&amp;quot; using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 13. (p. 30) Demostrar que &lt;br /&gt;
     longitud (conc xs ys) = longitud xs + longitud ys&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. longitud (conc [] ys) =&lt;br /&gt;
                          longitud [] + longitud ys&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             longitud (conc xs ys) =&lt;br /&gt;
                             longitud xs + longitud ys ⟹&lt;br /&gt;
                             longitud (conc (a # xs) ys) =&lt;br /&gt;
                             longitud (a # xs) + longitud ys *) &lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (conc xs ys)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud xs + longitud ys&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = longitud (x # xs) + longitud ys&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Inducción correspondiente a la definición recursiva *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 14. Definir la función&lt;br /&gt;
     coge :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (coge n xs) es la lista de los n primeros elementos de xs. Por &lt;br /&gt;
  ejemplo, &lt;br /&gt;
     coge 2 [a,c,d,b,e] = [a,c]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun coge :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;coge n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge 0 xs           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge (Suc n) (x#xs) = x # (coge n xs)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;coge 2 [a,c,d,b,e] = [a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 15. Definir la función&lt;br /&gt;
     elimina :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (elimina n xs) es la lista obtenida eliminando los n primeros&lt;br /&gt;
  elementos de xs. Por ejemplo, &lt;br /&gt;
     elimina 2 [a,c,d,b,e] = [d,b,e]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun elimina :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;elimina n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;elimina 0 xs           = xs&amp;quot;&lt;br /&gt;
| &amp;quot;elimina (Suc n) (x#xs) = elimina n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;elimina 2 [a,c,d,b,e] = [d,b,e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  La definición coge genera el esquema de inducción coge.induct:&lt;br /&gt;
     ⟦⋀n. P n []; &lt;br /&gt;
      ⋀x xs. P 0 (x#xs); &lt;br /&gt;
      ⋀n x xs. P n xs ⟹ P (Suc n) (x#xs)⟧&lt;br /&gt;
     ⟹ P n x&lt;br /&gt;
&lt;br /&gt;
  Puede verse usando &amp;quot;thm coge.induct&amp;quot;. *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 16. (p. 35) Demostrar que &lt;br /&gt;
     conc (coge n xs) (elimina n xs) = xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  apply (induct rule: coge.induct) &lt;br /&gt;
      (*  1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
          2. ⋀v va. conc (coge 0 (v # va)) (elimina 0 (v # va)) =&lt;br /&gt;
                     v # va&lt;br /&gt;
          3. ⋀n x xs. conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
                       conc (coge (Suc n) (x # xs)) &lt;br /&gt;
                            (elimina (Suc n) (x # xs)) =&lt;br /&gt;
                       x # xs *)&lt;br /&gt;
    apply simp_all&lt;br /&gt;
      (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  by (induct rule: coge.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n x xs&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x#(conc (coge n xs) (elimina n xs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x#xs&amp;quot; using HI by simp  &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario sobre la demostración anterior:&lt;br /&gt;
  · (induct rule: coge.induct) indica que el método de demostración es&lt;br /&gt;
    por el esquema de inducción correspondiente a la definición de la&lt;br /&gt;
    función coge.&lt;br /&gt;
  · Se generan 3 subobjetivos:&lt;br /&gt;
    · 1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
    · 2. ⋀x xs. conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&lt;br /&gt;
    · 3. ⋀n x xs. &lt;br /&gt;
            conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
            conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = x#xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por casos *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 17. Definir la función&lt;br /&gt;
     esVacia :: &amp;#039;a list ⇒ bool&lt;br /&gt;
  tal que (esVacia xs) se verifica si xs es la lista vacía. Por ejemplo,&lt;br /&gt;
     esVacia []  = True&lt;br /&gt;
     esVacia [1] = False&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun esVacia :: &amp;quot;&amp;#039;a list ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;esVacia []     = True&amp;quot;&lt;br /&gt;
| &amp;quot;esVacia (x#xs) = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;esVacia []  = True&amp;quot;&lt;br /&gt;
value &amp;quot;esVacia [a] = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 18 (p. 39) . Demostrar que &lt;br /&gt;
     esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                    esVacia xs = esVacia (conc xs xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; es el método de demostración por casos según xs.&lt;br /&gt;
  · Se generan dos subobjetivos  correspondientes a los dos&lt;br /&gt;
    constructores de listas:&lt;br /&gt;
    · 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
    · 2. ⋀y ys. xs = y#ys ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica &amp;quot;usando la propiedad anterior&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &amp;quot;assume xs = []&amp;quot;&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &amp;quot;fix y ys assume xs = y#ys&amp;quot;&lt;br /&gt;
  · &amp;quot;thus&amp;quot; es una abreviatura de &amp;quot;then show&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración con el patrón sugerido es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case (Cons x xs)&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Heurística de generalización *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 19. Definir la función&lt;br /&gt;
     inversaAc :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversaAc xs) es a inversa de xs calculada usando&lt;br /&gt;
  acumuladores. Por ejemplo, &lt;br /&gt;
     inversaAc [a,c,b,e] = [e,b,c,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun inversaAcAux :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAcAux [] ys     = ys&amp;quot;&lt;br /&gt;
| &amp;quot;inversaAcAux (x#xs) ys = inversaAcAux xs (x#ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition inversaAc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAc xs = inversaAcAux xs []&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversaAc [a,c,b,e] = [e,b,c,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Lema. [Ejemplo de equivalencia entre las definiciones]&lt;br /&gt;
  La inversa de [a,b,c] es lo mismo calculada con la primera definición&lt;br /&gt;
  que con la segunda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc [a,b,c] = inversa [a,b,c]&amp;quot;&lt;br /&gt;
  by (simp add: inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. [Ejemplo fallido de demostración por inducción]&lt;br /&gt;
  El siguiente intento de demostrar que para cualquier lista xs, se&lt;br /&gt;
  tiene que  &amp;quot;inversaAc xs = inversa xs&amp;quot; falla.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;inversaAc [] = inversa []&amp;quot; by (simp add: inversaAc_def)&lt;br /&gt;
next&lt;br /&gt;
  fix a xs assume HI: &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  have &amp;quot;inversaAc (a#xs) = inversaAcAux (a#xs) []&amp;quot; &lt;br /&gt;
    by (simp add: inversaAc_def)&lt;br /&gt;
  also have &amp;quot;… = inversaAcAux xs [a]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = inversa (a#xs)&amp;quot;&lt;br /&gt;
  (* Problema: la hipótesis de inducción no es aplicable. *)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Nota. [Heurística de generalización]&lt;br /&gt;
  Cuando se use demostración estructural, cuantificar universalmente las &lt;br /&gt;
  variables libres (o, equivalentemente, considerar las variables libres&lt;br /&gt;
  como variables arbitrarias).&lt;br /&gt;
&lt;br /&gt;
  Lema. [Lema con generalización]&lt;br /&gt;
  Para toda lista ys se tiene &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 20. (p. 44) Demostrar que &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  apply (induct xs arbitrary: ys) &lt;br /&gt;
     (* 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
        2. ⋀a xs ys.&lt;br /&gt;
              (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
              inversaAcAux (a # xs) ys = inversa (a # xs) @ ys *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  by (induct xs arbitrary: ys) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma inversaAcAux_es_inversa:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux [] ys = (inversa [])@ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs &lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; using HI by simp&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; using [[simp_trace]] by simp &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(induct xs arbitrary: ys)&amp;quot; es el método de demostración por&lt;br /&gt;
    inducción sobre xs usando ys como variable arbitraria.&lt;br /&gt;
  · Se generan dos subobjetivos:&lt;br /&gt;
    · 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
    · 2. ⋀a xs ys. (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
                    inversaAcAux (a # xs) ys = inversa (a # xs) @ ys&lt;br /&gt;
  · Dentro de una demostración se pueden incluir otras demostraciones.&lt;br /&gt;
  · Para demostrar la propiedad universal &amp;quot;⋀ys. P(ys)&amp;quot; se elige una&lt;br /&gt;
    lista arbitraria (con &amp;quot;fix ys&amp;quot;) y se demuestra &amp;quot;P(ys)&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. En el paso &amp;quot;inversa xs@(a#ys) = inversa (a#xs)@ys&amp;quot; se usan&lt;br /&gt;
  lemas de la teoría List. Se puede observar, insertano &lt;br /&gt;
     using [[simp_trace]]&lt;br /&gt;
  entre la igualdad y by simp, que los lemas usados son &lt;br /&gt;
  · List.append_simps_1: []@ys = ys&lt;br /&gt;
  · List.append_simps_2: (x#xs)@ys = x#(xs@ys)&lt;br /&gt;
  · List.append_assoc:   (xs @ ys) @ zs = xs @ (ys @ zs)&lt;br /&gt;
  Las dos primeras son las ecuaciones de la definición de append.&lt;br /&gt;
&lt;br /&gt;
  En la siguiente demostración se detallan los lemas utilizados.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2))&lt;br /&gt;
    (* inversa xs @ (a # ys) = (inversa xs @ [a]) @ ys*)&lt;br /&gt;
  apply (simp only: append_assoc)&lt;br /&gt;
    (* inversa xs @ (a # ys) = inversa xs @ ([a] @ ys) *)&lt;br /&gt;
  apply (simp only: append.simps(2))&lt;br /&gt;
    (* inversa xs @ (a # ys) = inversa xs @ (a # ([] @ ys)) *)&lt;br /&gt;
  apply (simp only: append.simps(1))&lt;br /&gt;
    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(inversa xs)@(a#ys) = (inversa xs)@(a#([]@ys))&amp;quot; &lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (inversa xs)@([a]@ys)&amp;quot; by (simp only: append.simps(2))&lt;br /&gt;
  also have &amp;quot;… = ((inversa xs)@[a])@ys&amp;quot; by (simp only: append_assoc)&lt;br /&gt;
  also have &amp;quot;… = (inversa (a#xs))@ys&amp;quot; by (simp only: inversa.simps(2))&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 21. (p. 43) Demostrar que &lt;br /&gt;
     inversaAc xs = inversa xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  apply (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  by (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario de la demostración anterior:&lt;br /&gt;
  · &amp;quot;(simp add: inversaAcAux_es_inversa inversaAc_def)&amp;quot; es el método de &lt;br /&gt;
    demostración por simplificación usando como regla de simplificación &lt;br /&gt;
    las propiedades inversaAcAux_es_inversa e inversaAc_def. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Demostración por inducción para funciones de orden superior *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 22. Definir la función&lt;br /&gt;
     sum :: nat list ⇒ nat&lt;br /&gt;
  tal que (sum xs) es la suma de los elementos de xs. Por ejemplo,&lt;br /&gt;
     sum [3,2,5] = 10&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun sum :: &amp;quot;nat list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sum []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;sum (x#xs) = x + sum xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sum [3,2,5] = 10&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 23. Definir la función&lt;br /&gt;
     map :: (&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&lt;br /&gt;
  tal que (map f xs) es la lista obtenida aplicando la función f a los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     map (λx. 2*x) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map (( * ) 2) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map ((+) 2)   [3::nat,2,5] = [5,4,7]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun map :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&amp;quot; where&lt;br /&gt;
  &amp;quot;map f []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;map f (x#xs) = (f x) # map f xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;map (λx. 2*x) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map (( * ) 2) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map ((+) 2)   [3::nat,2,5] = [5,4,7]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 24. (p. 45) Demostrar que &lt;br /&gt;
     sum (map (( * ) 2) xs) = 2 * (sum xs)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. sum (map (( * ) 2) []) = 2 * sum []&lt;br /&gt;
        2. ⋀a xs. sum (map (( * ) 2) xs) = 2 * sum xs ⟹&lt;br /&gt;
                  sum (map (( * ) 2) (a # xs)) = 2 * sum (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map (( * ) 2) []) = 2 * (sum [])&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map (( * ) 2) (a#xs)) = sum ((2*a)#(map (( * ) 2) xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 2*a + sum (map (( * ) 2) xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 2*a + 2*(sum xs)&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = 2*(a + sum xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 2*(sum (a#xs))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;sum (map (( * ) 2) (a#xs)) = 2*(sum (a#xs))&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 25. (p. 48) Demostrar que &lt;br /&gt;
     longitud (map f xs) = longitud xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. longitud (map f []) = longitud []&lt;br /&gt;
        2. ⋀a xs. longitud (map f xs) = longitud xs ⟹&lt;br /&gt;
                   longitud (map f (a # xs)) = longitud (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (map f xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud xs&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = longitud (a#xs)&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Referencias *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  · J.A. Alonso. &amp;quot;Razonamiento sobre programas&amp;quot; http://goo.gl/R06O3&lt;br /&gt;
  · G. Hutton. &amp;quot;Programming in Haskell&amp;quot;. Cap. 13 &amp;quot;Reasoning about&lt;br /&gt;
    programms&amp;quot;. &lt;br /&gt;
  · S. Thompson. &amp;quot;Haskell: the Craft of Functional Programming, 3rd&lt;br /&gt;
    Edition. Cap. 8 &amp;quot;Reasoning about programms&amp;quot;. &lt;br /&gt;
  · L. Paulson. &amp;quot;ML for the Working Programmer, 2nd Edition&amp;quot;. Cap. 6. &lt;br /&gt;
    &amp;quot;Reasoning about functional programs&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_por_casos_y_por_inducci%C2%A2n&amp;diff=622</id>
		<title>Razonamiento por casos y por inducci¢n</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_por_casos_y_por_inducci%C2%A2n&amp;diff=622"/>
		<updated>2019-05-01T14:45:22Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 7: Razonamiento por casos y por inducción *}&lt;br /&gt;
&lt;br /&gt;
theory T7_Razonamiento_por_casos_y_por_induccion&lt;br /&gt;
imports Main HOL.Parity&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En este tema se amplían los métodos de demostración por casos y por&lt;br /&gt;
  inducción iniciados en el tema anterior.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por distinción de casos *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Distinción de casos booleanos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por distinción de casos booleanos:&lt;br /&gt;
  Demostrar &amp;quot;¬A ∨ A&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply cases           (* 1. ?P ⟹ ¬ A ∨ A&lt;br /&gt;
                           2. ¬ ?P ⟹ ¬ A ∨ A  *)&lt;br /&gt;
   apply (erule disjI2) (* 1. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
  apply (erule disjI1)  (* No subgoals! *)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply cases     (* 1. ?P ⟹ ¬ A ∨ A&lt;br /&gt;
                     2. ¬ ?P ⟹ ¬ A ∨ A  *)&lt;br /&gt;
   apply simp_all (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
proof cases&lt;br /&gt;
  assume &amp;quot;A&amp;quot; &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;¬A&amp;quot; &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios de la demostración anterior:&lt;br /&gt;
  · &amp;quot;proof cases&amp;quot; indica que el método de demostración será por&lt;br /&gt;
    distinción de casos. &lt;br /&gt;
  · Se generan 2 casos:&lt;br /&gt;
       1. ?P ⟹ ¬A ∨ A&lt;br /&gt;
       2. ¬?P ⟹ ¬A ∨ A&lt;br /&gt;
    donde ?P es una variable sobre las fórmulas.&lt;br /&gt;
  · (assume &amp;quot;A&amp;quot;) indica que se está usando &amp;quot;A&amp;quot; en lugar de la variable&lt;br /&gt;
    ?P.&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica usando la fórmula anterior.&lt;br /&gt;
  · &amp;quot;..&amp;quot; indica usando la regla lógica necesaria (las reglas lógicas se&lt;br /&gt;
    estudiarán en los siguientes temas).&lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente caso (se puede observar cómo ha&lt;br /&gt;
    sustituido ¬?P por ¬A.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por distinción de casos booleanos con nombres: &lt;br /&gt;
  Demostrar &amp;quot;¬A ∨ A&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply (cases &amp;quot;A&amp;quot;)     (* 1. A ⟹ ¬ A ∨ A&lt;br /&gt;
                           2. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
   apply (erule disjI2) (* 1. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
  apply (erule disjI1)  (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  apply (cases &amp;quot;A&amp;quot;)     (* 1. A ⟹ ¬ A ∨ A&lt;br /&gt;
                           2. ¬ A ⟹ ¬ A ∨ A *)&lt;br /&gt;
   apply simp_all       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma &amp;quot;¬A ∨ A&amp;quot; &lt;br /&gt;
proof (cases &amp;quot;A&amp;quot;)&lt;br /&gt;
  case True &lt;br /&gt;
  then show &amp;quot;¬A ∨ A&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  case False &lt;br /&gt;
  thus &amp;quot;¬A ∨ A&amp;quot; .. &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (cases &amp;quot;A&amp;quot;) indica que la demostración se hará por casos según los&lt;br /&gt;
    distintos valores de &amp;quot;A&amp;quot;.&lt;br /&gt;
  · Como &amp;quot;A&amp;quot; es una fórmula, sus posibles valores son verdadero o falso.&lt;br /&gt;
  · &amp;quot;case True&amp;quot; indica que se está suponiendo que A es verdadera. Es&lt;br /&gt;
    equivalente a &amp;quot;assume A&amp;quot;.&lt;br /&gt;
  · &amp;quot;case False&amp;quot; indica que se está suponiendo que A es falsa. Es&lt;br /&gt;
    equivalente a &amp;quot;assume ¬A&amp;quot;.&lt;br /&gt;
  · En general, &lt;br /&gt;
    · el método (cases F) es una abreviatura de la aplicación de la regla&lt;br /&gt;
         ⟦F ⟹ Q; ¬F ⟹ Q⟧ ⟹ Q  &lt;br /&gt;
    · La expresión &amp;quot;case True&amp;quot; es una abreviatura de F.&lt;br /&gt;
    · La expresión &amp;quot;case False&amp;quot; es una abreviatura de ¬F.&lt;br /&gt;
  · Ventajas de &amp;quot;cases&amp;quot; con nombre: &lt;br /&gt;
    · reduce la escritura de la fórmula y&lt;br /&gt;
    · es independiente del orden de los casos.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Distinción de casos sobre otros tipos de datos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de distinción de casos sobre listas: &lt;br /&gt;
  Demostrar que la longitud del resto de una lista es la longitud de la&lt;br /&gt;
  lista menos 1. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  apply (cases xs)&lt;br /&gt;
     (*  1. xs = [] ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
         2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                     length (tl xs) = length xs - 1*)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;length (tl xs) = length xs - 1&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;length(tl xs) = length xs - 1&amp;quot; by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; indica que la demostración se hará por casos sobre los&lt;br /&gt;
    posibles valores de xs.&lt;br /&gt;
  · Como xs es una lista, sus posibles valores son la lista vacía ([]) o&lt;br /&gt;
    una lista no vacía (de la forma (y#ys)).&lt;br /&gt;
  · Se generan 2 casos:&lt;br /&gt;
       1. xs = [] ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
       2. ⋀a list. xs = a # list ⟹ length (tl xs) = length xs - 1&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración simplificada es› &lt;br /&gt;
lemma &amp;quot;length (tl xs) = length xs - 1&amp;quot; &lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons &lt;br /&gt;
  then show ?thesis by simp &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &lt;br /&gt;
       &amp;quot;assume xs =[]&amp;quot;.&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &lt;br /&gt;
       &amp;quot;fix y ys assume xs = y#ys&amp;quot;&lt;br /&gt;
  · ?thesis es una abreviatura de la conclusión del lema.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En el siguiente ejemplo vamos a demostrar una propiedad de la función&lt;br /&gt;
  drop que está definida en la teoría List de forma que (drop n xs) la&lt;br /&gt;
  lista obtenida eliminando en xs} los n primeros elementos. Su&lt;br /&gt;
  definición es la siguiente   &lt;br /&gt;
     drop_Nil:  &amp;quot;drop n []     = []&amp;quot; &lt;br /&gt;
     drop_Cons: &amp;quot;drop n (x#xs) = (case n of &lt;br /&gt;
                                    0 =&amp;gt; x#xs | &lt;br /&gt;
                                    Suc(m) =&amp;gt; drop m xs)&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de análisis de casos:&lt;br /&gt;
  Demostrar que el resultado de eliminar los n+1 primeros elementos de&lt;br /&gt;
  xs es el mismo que eliminar los n primeros elementos del resto de xs.  &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es› &lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ drop (n + 1) xs = drop n (tl xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                     drop (n + 1) xs = drop n (tl xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
  by (cases xs) auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;drop (n + 1) xs = drop n (tl xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons &lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Inducción matemática *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  [Principio de inducción matemática]&lt;br /&gt;
  Para demostrar una propiedad P para todos los números naturales basta&lt;br /&gt;
  probar que el 0 tiene la propiedad P y que si n tiene la propiedad P,&lt;br /&gt;
  entonces n+1 también la tiene. &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción matemática está formalizado en&lt;br /&gt;
  el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*  &lt;br /&gt;
  Ejemplo de demostración por inducción: Usaremos el principio de&lt;br /&gt;
  inducción matemática para demostrar que &lt;br /&gt;
     1 + 3 + ... + (2n-1) = n^2&lt;br /&gt;
&lt;br /&gt;
  Definición. [Suma de los primeros impares] &lt;br /&gt;
  (suma_impares n) la suma de los n números impares. Por ejemplo,&lt;br /&gt;
     suma_impares 3  =  9&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun suma_impares :: &amp;quot;nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;suma_impares 0 = 0&amp;quot; &lt;br /&gt;
| &amp;quot;suma_impares (Suc n) = (2*(Suc n) - 1) + suma_impares n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;suma_impares 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por inducción matemática:&lt;br /&gt;
  Demostrar que la suma de los n primeros números impares es n^2.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración aplicativa es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  apply (induct n) &lt;br /&gt;
     (* 1. suma_impares 0 = 0 * 0&lt;br /&gt;
        2. ⋀n. suma_impares n = n * n ⟹&lt;br /&gt;
                suma_impares (Suc n) = Suc n * Suc n*) &lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *) &lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración del lema anterior por inducción y razonamiento &lt;br /&gt;
   ecuacional›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;suma_impares 0 = 0 * 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n assume HI: &amp;quot;suma_impares n = n * n&amp;quot;&lt;br /&gt;
  have &amp;quot;suma_impares (Suc n) = (2 * (Suc n) - 1) + suma_impares n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (2 * (Suc n) - 1) + n * n&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;… = n * n + 2 * n + 1&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;suma_impares (Suc n) = (Suc n) * (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración del lema anterior con patrones y razonamiento &lt;br /&gt;
   ecuacional›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;?P 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume HI: &amp;quot;?P n&amp;quot;&lt;br /&gt;
  have &amp;quot;suma_impares (Suc n) = (2 * (Suc n) - 1) + suma_impares n&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;… = (2 * (Suc n) - 1) + n * n&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;… = n * n + 2 * n + 1&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;?P (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario sobre la demostración anterior:&lt;br /&gt;
  · Con la expresión&lt;br /&gt;
       &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
    se abrevia &amp;quot;suma_impares n = n * n&amp;quot; como &amp;quot;?P n&amp;quot;. Por tanto, &lt;br /&gt;
       &amp;quot;?P 0&amp;quot;       es una abreviatura de &amp;quot;suma_impares 0 = 0 * 0&amp;quot;&lt;br /&gt;
       &amp;quot;?P (Suc n)&amp;quot; es una abreviatura de &amp;quot;suma_impares (Suc n) = &lt;br /&gt;
                                           (Suc n) * (Suc n)&amp;quot;&lt;br /&gt;
  · En general, cualquier fórmula seguida de (is patrón) equipara el&lt;br /&gt;
    patrón con la fórmula. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración usando patrones es›&lt;br /&gt;
lemma &amp;quot;suma_impares n = n * n&amp;quot; (is &amp;quot;?P n&amp;quot;)&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;?P 0&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;?P n&amp;quot;&lt;br /&gt;
  then show &amp;quot;?P (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
  &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de definición con existenciales. &lt;br /&gt;
  Un número natural n es par si existe un natural m tal que n=m+m.   &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition par :: &amp;quot;nat ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;par n ≡ ∃m. n=m+m&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*                                &lt;br /&gt;
  Ejemplo de inducción y existenciales: &lt;br /&gt;
  Demostrar que para todo número natural n, se verifica que n*(n+1) par. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración aplicativa›&lt;br /&gt;
lemma &lt;br /&gt;
  shows &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  apply (induct n)&lt;br /&gt;
     (* par (0 * (0 + 1))&lt;br /&gt;
        ⋀n. par (n * (n + 1)) ⟹ par (Suc n * (Suc n + 1)) *)&lt;br /&gt;
   apply (simp add: par_def)&lt;br /&gt;
     (* ⋀n. par (n * (n + 1)) ⟹ par (Suc n * (Suc n + 1)) *)&lt;br /&gt;
  apply (simp add: par_def)&lt;br /&gt;
     (* ⋀n. ∃m. n + n * n = m + m ⟹&lt;br /&gt;
             ∃m. Suc (Suc (n + (n + (n + n * n)))) = m + m *)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
     (* ⋀n m. n + n * n = m + m ⟹&lt;br /&gt;
              ∃m. Suc (Suc (n + (n + (n + n * n)))) = m + m*)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;m+n+1&amp;quot; in exI)&lt;br /&gt;
     (* ⋀n m. n + n * n = m + m ⟹&lt;br /&gt;
              Suc (Suc (n + (n + (n + n * n)))) =&lt;br /&gt;
              m + n + 1 + (m + n + 1)*)&lt;br /&gt;
  apply simp&lt;br /&gt;
     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
― ‹Demostración declarativa›&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;par (0*(0+1))&amp;quot; by (simp add: par_def)&lt;br /&gt;
next&lt;br /&gt;
  fix n &lt;br /&gt;
  assume &amp;quot;par (n*(n+1))&amp;quot;&lt;br /&gt;
  then have &amp;quot;∃m. n*(n+1) = m+m&amp;quot; by (simp add:par_def)&lt;br /&gt;
  then obtain m where m: &amp;quot;n*(n+1) = m+m&amp;quot; ..&lt;br /&gt;
  then have &amp;quot;(Suc n)*((Suc n)+1) = (m+n+1)+(m+n+1)&amp;quot; by auto&lt;br /&gt;
  then have &amp;quot;∃m. (Suc n)*((Suc n)+1) = m+m&amp;quot; ..&lt;br /&gt;
  then show &amp;quot;par ((Suc n)*((Suc n)+1))&amp;quot; by (simp add:par_def)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (fixes n :: &amp;quot;nat&amp;quot;) es una abreviatura de &amp;quot;sea n un número natural&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En Isabelle puede demostrarse de manera más simple un lema equivalente&lt;br /&gt;
  usando en lugar de la función &amp;quot;par&amp;quot; la función &amp;quot;even&amp;quot; definida en la&lt;br /&gt;
  teoría Parity por&lt;br /&gt;
     even x ⟷ x mod 2 = 0&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;even (n*(n+1))&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · Para poder usar la función &amp;quot;even&amp;quot; de la librería Parity es necesario&lt;br /&gt;
    importar dicha librería. Por ello, antes del inicio de la teoría&lt;br /&gt;
    aparece &lt;br /&gt;
       imports Main Parity&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Para completar la demostración basta demostrar la equivalencia de las&lt;br /&gt;
  funciones &amp;quot;par&amp;quot; y &amp;quot;even&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &lt;br /&gt;
  fixes n :: &amp;quot;nat&amp;quot;&lt;br /&gt;
  shows &amp;quot;par n = even n&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;par n = (∃m. n = m+m)&amp;quot; by (simp add:par_def)&lt;br /&gt;
  then show &amp;quot;par n = even n&amp;quot; by presburger&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;by presburger&amp;quot; indica que se use como método de demostración el&lt;br /&gt;
    algoritmo de decisión de la aritmética de Presburger.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Inducción estructural *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Inducción estructural:&lt;br /&gt;
  · En Isabelle puede hacerse inducción estructural sobre cualquier tipo&lt;br /&gt;
    recursivo.&lt;br /&gt;
  · La inducción matemática es la inducción estructural sobre el tipo de&lt;br /&gt;
    los naturales.&lt;br /&gt;
  · El esquema de inducción estructural sobre listas es&lt;br /&gt;
    · list.induct: ⟦P []; ⋀x ys. P ys ⟹ P (x # ys)⟧ ⟹ P zs&lt;br /&gt;
  · Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
    que la lista vacía tiene la propiedad y que al añadir un elemento a una&lt;br /&gt;
    lista que tiene la propiedad se obtiene una lista que también tiene la&lt;br /&gt;
    propiedad. &lt;br /&gt;
  · En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
    mediante el teorema list.induct que puede verse con &lt;br /&gt;
       thm list.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Concatenación de listas:&lt;br /&gt;
  En la teoría List.thy está definida la concatenación de listas (que&lt;br /&gt;
  se representa por @) como sigue&lt;br /&gt;
     append_Nil:  &amp;quot;[]@ys     = ys&amp;quot;&lt;br /&gt;
     append_Cons: &amp;quot;(x#xs)@ys = x#(xs@ys)&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Lema. [Ejemplo de inducción sobre listas]&lt;br /&gt;
  Demostrar que la concatenación de listas es asociativa.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma conc_asociativa: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;[] @ (ys @ zs) = ([] @ ys) @ zs&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;[] @ (ys @ zs) = ys @ zs&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = ([] @ ys) @ zs&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
  show &amp;quot;(x#xs) @ (ys @ zs) = ((x#xs) @ ys) @ zs&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    have &amp;quot;(x#xs) @ (ys @ zs) = x#(xs @ (ys @ zs))&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = x#((xs @ ys) @ zs)&amp;quot; using HI by simp&lt;br /&gt;
    also have &amp;quot;… = (x#(xs @ ys)) @ zs&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = ((x#xs) @ ys) @ zs&amp;quot; by simp&lt;br /&gt;
    finally show ?thesis .&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es› &lt;br /&gt;
lemma conc_asociativa_1: &amp;quot;xs @ (ys @ zs) = (xs @ ys) @ zs&amp;quot;&lt;br /&gt;
by (induct xs) auto&lt;br /&gt;
&lt;br /&gt;
section {* Heurísticas para la inducción *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Definición. [Definición recursiva de inversa]&lt;br /&gt;
  (inversa xs) la inversa de la lista xs. Por ejemplo,&lt;br /&gt;
     inversa [a,b,c] = [c,b,a] &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun inversa :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversa [] = []&amp;quot; &lt;br /&gt;
| &amp;quot;inversa (x#xs) = (inversa xs) @ [x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversa [a,b,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Definición. [Definición de inversa con acumuladores]&lt;br /&gt;
  (inversaAc xs) es la inversa de la lista xs calculada con&lt;br /&gt;
  acumuladores. Por ejemplo,&lt;br /&gt;
     inversaAc [a,b,c]       = [c,b,a] &lt;br /&gt;
     inversaAcAux [a,b,c] [] = [c,b,a] &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun inversaAcAux :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAcAux [] ys     = ys&amp;quot; &lt;br /&gt;
| &amp;quot;inversaAcAux (x#xs) ys = inversaAcAux xs (x#ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
definition inversaAc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAc xs ≡ inversaAcAux xs []&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversaAcAux [a,b,c] []&amp;quot;&lt;br /&gt;
value &amp;quot;inversaAc [a,b,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Lema. [Ejemplo de equivalencia entre las definiciones]&lt;br /&gt;
  La inversa de [a,b,c] es lo mismo calculada con la primera definición&lt;br /&gt;
  que con la segunda.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc [a,b,c] = inversa [a,b,c]&amp;quot;&lt;br /&gt;
by (simp add: inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. [Ejemplo fallido de demostración por inducción]&lt;br /&gt;
  El siguiente intento de demostrar que para cualquier lista xs, se&lt;br /&gt;
  tiene que  &amp;quot;inversaAc xs = inversa xs&amp;quot; falla.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;inversaAc [] = inversa []&amp;quot; by (simp add: inversaAc_def)&lt;br /&gt;
next&lt;br /&gt;
  fix a xs assume HI: &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  have &amp;quot;inversaAc (a#xs) = inversaAcAux (a#xs) []&amp;quot; &lt;br /&gt;
    by (simp add: inversaAc_def)&lt;br /&gt;
  also have &amp;quot;… = inversaAcAux xs [a]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;… = inversa (a#xs)&amp;quot;&lt;br /&gt;
  (* Problema: la hipótesis de inducción no es aplicable. *)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Nota. [Heurística de generalización]&lt;br /&gt;
  Cuando se use demostración estructural, cuantificar universalmente las &lt;br /&gt;
  variables libres (o, equivalentemente, considerar las variables libres&lt;br /&gt;
  como variables arbitrarias).&lt;br /&gt;
&lt;br /&gt;
  Lema. [Lema con generalización]&lt;br /&gt;
  Para toda lista ys se tiene &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es› &lt;br /&gt;
lemma inversaAcAux_es_inversa:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux [] ys = (inversa [])@ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs &lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; using HI by simp&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; using [[simp_trace]] by simp &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma inversaAcAux_es_inversa_1:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
by (induct xs arbitrary: ys) auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Corolario.  Para cualquier lista xs, se tiene que&lt;br /&gt;
     inversaAc xs = inversa xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  using [[simp_trace]] &lt;br /&gt;
  by (simp add: inversaAcAux_es_inversa inversaAc_def)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota. En el paso &amp;quot;inversa xs@(a#ys) = inversa (a#xs)@ys&amp;quot; se usan&lt;br /&gt;
  lemas de la teoría List. Se puede observar, insertano &lt;br /&gt;
     using [[simp_trace]]&lt;br /&gt;
  entre la igualdad y by simp, que los lemas usados son &lt;br /&gt;
  · List.append_simps_1: []@ys = ys&lt;br /&gt;
  · List.append_simps_2: (x#xs)@ys = x#(xs@ys)&lt;br /&gt;
  · List.append_assoc:   (xs @ ys) @ zs = xs @ (ys @ zs)&lt;br /&gt;
  Las dos primeras son las ecuaciones de la definición de append.&lt;br /&gt;
&lt;br /&gt;
  En la siguiente demostración se detallan los lemas utilizados.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(inversa xs)@(a#ys) = (inversa (a#xs))@ys&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;(inversa xs)@(a#ys) = (inversa xs)@(a#([]@ys))&amp;quot; &lt;br /&gt;
    by (simp only: append.simps(1))&lt;br /&gt;
  also have &amp;quot;… = (inversa xs)@([a]@ys)&amp;quot; by (simp only: append.simps(2))&lt;br /&gt;
  also have &amp;quot;… = ((inversa xs)@[a])@ys&amp;quot; by (simp only: append_assoc)&lt;br /&gt;
  also have &amp;quot;… = (inversa (a#xs))@ys&amp;quot; by (simp only: inversa.simps(2))&lt;br /&gt;
  finally show ?thesis .&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Recursión general. La función de Ackermann *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  El objetivo de esta sección es mostrar el uso de las definiciones&lt;br /&gt;
  recursivas generales y sus esquemas de inducción. Como ejemplo se usa la&lt;br /&gt;
  función de Ackermann (se puede consultar información sobre dicha función en&lt;br /&gt;
  http://en.wikipedia.org/wiki/Ackermann_function).&lt;br /&gt;
&lt;br /&gt;
  Definición.  La función de Ackermann se define por&lt;br /&gt;
    A(m,n) = n+1,             si m=0,&lt;br /&gt;
             A(m-1,1),        si m&amp;gt;0 y n=0,&lt;br /&gt;
             A(m-1,A(m,n-1)), si m&amp;gt;0 y n&amp;gt;0&lt;br /&gt;
  para todo los números naturales. &lt;br /&gt;
&lt;br /&gt;
  La función de Ackermann es recursiva, pero no es primitiva recursiva. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun ack :: &amp;quot;nat ⇒ nat ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;ack 0       n       = n+1&amp;quot; &lt;br /&gt;
| &amp;quot;ack (Suc m) 0       = ack m 1&amp;quot; &lt;br /&gt;
| &amp;quot;ack (Suc m) (Suc n) = ack m (ack (Suc m) n)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
― ‹Ejemplo de evaluación›&lt;br /&gt;
value &amp;quot;ack 2 3&amp;quot; (* devuelve 9 *)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Esquema de inducción correspondiente a una función:&lt;br /&gt;
  · Al definir una función recursiva general se genera una regla de&lt;br /&gt;
    inducción. En la definición anterior, la regla generada es&lt;br /&gt;
    ack.induct: &lt;br /&gt;
       ⟦⋀n. P 0 n; &lt;br /&gt;
        ⋀m. P m 1 ⟹ P (Suc m) 0;&lt;br /&gt;
        ⋀m n. ⟦P (Suc m) n; P m (ack (Suc m) n)⟧ ⟹ P (Suc m) (Suc n)⟧&lt;br /&gt;
       ⟹ P a b&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de demostración por la inducción correspondiente a una función:&lt;br /&gt;
  Demostrar que para todos m y n, A(m,n) &amp;gt; n.&lt;br /&gt;
*} &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
proof (induct m n rule: ack.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;ack 0 n &amp;gt; n&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix m &lt;br /&gt;
  assume &amp;quot;ack m 1 &amp;gt; 1&amp;quot;&lt;br /&gt;
  then show &amp;quot;ack (Suc m) 0 &amp;gt; 0&amp;quot; by simp&lt;br /&gt;
next  &lt;br /&gt;
  fix m n&lt;br /&gt;
  assume &amp;quot;n &amp;lt; ack (Suc m) n&amp;quot; and &lt;br /&gt;
         &amp;quot;ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)&amp;quot;&lt;br /&gt;
  then show &amp;quot;Suc n &amp;lt; ack (Suc m) (Suc n)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · (induct m n rule: ack.induct) indica que el método de demostración&lt;br /&gt;
    es el esquema de recursión correspondiente a la definición de &lt;br /&gt;
    (ack m n).&lt;br /&gt;
  · Se generan 3 casos:&lt;br /&gt;
    1. ⋀n. n &amp;lt; ack 0 n&lt;br /&gt;
    2. ⋀m. 1 &amp;lt; ack m 1 ⟹ 0 &amp;lt; ack (Suc m) 0&lt;br /&gt;
    3. ⋀m n. ⟦n &amp;lt; ack (Suc m) n; &lt;br /&gt;
              ack (Suc m) n &amp;lt; ack m (ack (Suc m) n)⟧&lt;br /&gt;
             ⟹ Suc n &amp;lt; ack (Suc m) (Suc n)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma &amp;quot;ack m n &amp;gt; n&amp;quot;&lt;br /&gt;
by (induct m n rule: ack.induct) auto&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=621</id>
		<title>Razonamiento sobre programas en Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=621"/>
		<updated>2019-05-01T14:13:14Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 6: Razonamiento sobre programas *}&lt;br /&gt;
&lt;br /&gt;
theory T6_Razonamiento_sobre_programas&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  En este tema se demuestra con Isabelle las propiedades de los&lt;br /&gt;
  programas funcionales de tema 6 http://bit.ly/2Za6YWY&lt;br /&gt;
&lt;br /&gt;
  Para cada propiedades se presentan distintos tipos de demostraciones:&lt;br /&gt;
  automáticas, aplicativas y declarativas. *} &lt;br /&gt;
&lt;br /&gt;
declare [[names_short]]&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento ecuacional *}&lt;br /&gt;
&lt;br /&gt;
text {* ----------------------------------------------------------------&lt;br /&gt;
  Ejemplo 1. Definir, por recursión, la función&lt;br /&gt;
     longitud :: &amp;#039;a list ⇒ nat&lt;br /&gt;
  tal que (longitud xs) es la longitud de la listas xs. Por ejemplo,&lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
fun longitud :: &amp;quot;&amp;#039;a list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;longitud []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;longitud (x#xs) = 1 + longitud xs&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
value &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 2. Demostrar que &lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 3. Definir la función&lt;br /&gt;
     fun intercambia :: &amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&lt;br /&gt;
  tal que (intercambia p) es el par obtenido intercambiando las&lt;br /&gt;
  componentes del par p. Por ejemplo,&lt;br /&gt;
     intercambia (u,v) = (v,u)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun intercambia :: &amp;quot;&amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;intercambia (x,y) = (y,x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;intercambia (u,v) = (v,u)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La definición de la función intercambia genera una regla de&lt;br /&gt;
  simplificación&lt;br /&gt;
  · intercambia.simps: intercambia (x,y) = (y,x)&lt;br /&gt;
  &lt;br /&gt;
  Se puede ver con &lt;br /&gt;
  · thm intercambia.simps &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm intercambia.simps&lt;br /&gt;
(* da intercambia (?x, ?y) = (?y, ?x) *)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 4. (p.6) Demostrar que &lt;br /&gt;
     intercambia (intercambia (x,y)) = (x,y)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by (simp only: intercambia.simps)&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  apply (simp only: intercambia.simps)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  by simp&lt;br /&gt;
  also have &amp;quot;... = (x,y)&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  also have &amp;quot;... = (x,y)&amp;quot; &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;by (simp only: intercambia.simps)&amp;quot; para indicar que sólo se usa&lt;br /&gt;
    como regla de escritura la correspondiente a la definición de&lt;br /&gt;
    intercambia,&lt;br /&gt;
  · &amp;quot;also&amp;quot; para encadenar pasos ecuacionales,&lt;br /&gt;
  · &amp;quot;...&amp;quot; para representar la derecha de la igualdad anterior en un&lt;br /&gt;
    razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;finally&amp;quot; para indicar el último pasa de un razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.&lt;br /&gt;
  · &amp;quot;by simp&amp;quot; para indicar el método de demostración por simplificación y &lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas,&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota: La diferencia entre las dos demostraciones es que en los dos&lt;br /&gt;
  primeros pasos no se explicita la regla de simplificación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 5. Definir, por recursión, la función&lt;br /&gt;
     inversa :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversa xs) es la lista obtenida invirtiendo el orden de los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     inversa [a,d,c] = [c,d,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun inversa :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversa []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;inversa (x#xs) = inversa xs @ [x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversa [a,d,c] = [c,d,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 6. (p. 9) Demostrar que &lt;br /&gt;
     inversa [x] = [x]&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En la demostración anterior se usaron las siguientes reglas:&lt;br /&gt;
  · inversa.simps(1): inversa [] = []&lt;br /&gt;
  · inversa.simps(2): inversa (x#xs) = inversa xs @ [x]&lt;br /&gt;
  · append_Nil:       [] @ ys = ys&lt;br /&gt;
  Vamos a explicitar su aplicación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2)) (* inversa [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: inversa.simps(1)) (* [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: append_Nil)       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = (inversa []) @ [x]&amp;quot; by (simp only: inversa.simps(2))&lt;br /&gt;
  also have &amp;quot;... = [] @ [x]&amp;quot; by (simp only: inversa.simps(1))&lt;br /&gt;
  also have &amp;quot;... = [x]&amp;quot; by (simp only: append_Nil) &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = (inversa []) @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = [] @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = [x]&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por inducción sobre los naturales *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  [Principio de inducción sobre los naturales] Para demostrar una&lt;br /&gt;
  propiedad P para todos los números naturales basta probar que el 0&lt;br /&gt;
  tiene la propiedad P y que si n tiene la propiedad P, entonces n+1&lt;br /&gt;
  también la tiene.  &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre los naturales está&lt;br /&gt;
  formalizado en el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 7. Definir la función&lt;br /&gt;
     repite :: nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (repite n x) es la lista formada por n copias del elemento&lt;br /&gt;
  x. Por ejemplo, &lt;br /&gt;
     repite 3 a = [a,a,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;repite 0 x       = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) x = x # (repite n x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;repite 3 a = [a,a,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 8. (p. 18) Demostrar que &lt;br /&gt;
     longitud (repite n x) = n&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp      (* 1. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
  apply simp       (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa con simp_all es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp_all  (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (repite n x)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + n&amp;quot; using HI by simp&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · A la derecha de proof se indica el método de la demostración.&lt;br /&gt;
  · (induct n) indica que la demostración se hará por inducción en n.&lt;br /&gt;
  · Se generan dos subobjetivos correspondientes a la base y el paso de&lt;br /&gt;
    inducción:&lt;br /&gt;
    1. longitud (repite 0 x) = 0&lt;br /&gt;
    2. ⋀n. longitud (repite n x) = n ⟹ &lt;br /&gt;
            longitud (repite (Suc n) x) = Suc n&lt;br /&gt;
    donde ⋀n se lee &amp;quot;para todo n&amp;quot;.  &lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente subobjetivo.&lt;br /&gt;
  · &amp;quot;fix n&amp;quot; indica &amp;quot;sea n un número natural cualquiera&amp;quot;&lt;br /&gt;
  · assume HI: &amp;quot;longitud (repite n x) = n&amp;quot; indica «supongamos que &lt;br /&gt;
    &amp;quot;longitud (repite n x) = n&amp;quot; y sea HI la etiqueta de este supuesto».&lt;br /&gt;
  · &amp;quot;using HI&amp;quot; usando la propiedad etiquetada con HI. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por inducción sobre listas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
  que la lista vacía tiene la propiedad y que al añadir un elemento a&lt;br /&gt;
  una lista que tiene la propiedad se obtiene otra lista que también&lt;br /&gt;
  tiene la propiedad. &lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
  mediante el teorema list.induct &lt;br /&gt;
     ⟦P []; &lt;br /&gt;
      ⋀x xs. P xs ⟹ P (x#xs)⟧ &lt;br /&gt;
     ⟹ P xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 9. Definir la función&lt;br /&gt;
     conc :: &amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (conc xs ys) es la concatención de las listas xs e ys. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun conc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;conc []     ys = ys&amp;quot;&lt;br /&gt;
| &amp;quot;conc (x#xs) ys = x # (conc xs ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 10. (p. 24) Demostrar que &lt;br /&gt;
     conc xs (conc ys zs) = (conc xs ys) zs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  apply (induct xs) (*  1. conc [] (conc ys zs) = conc (conc [] ys) zs&lt;br /&gt;
                        2. ⋀a xs.&lt;br /&gt;
                              conc xs (conc ys zs) =&lt;br /&gt;
                              conc (conc xs ys) zs ⟹&lt;br /&gt;
                              conc (a # xs) (conc ys zs) =&lt;br /&gt;
                              conc (conc (a # xs) ys) zs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x # (conc (conc xs ys) zs)&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = conc (conc (x # xs) ys) zs&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 11. Refutar que &lt;br /&gt;
     conc xs ys = conc ys xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;conc xs ys = conc ys xs&amp;quot;&lt;br /&gt;
  quickcheck&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Encuentra el contraejemplo, &lt;br /&gt;
  xs = [a2]&lt;br /&gt;
  ys = [a1] *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 12. (p. 28) Demostrar que &lt;br /&gt;
     conc xs [] = xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. conc [] [] = []&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             conc xs [] = xs ⟹&lt;br /&gt;
                             conc (a # xs) [] = a # xs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x # xs&amp;quot; using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 13. (p. 30) Demostrar que &lt;br /&gt;
     longitud (conc xs ys) = longitud xs + longitud ys&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. longitud (conc [] ys) =&lt;br /&gt;
                          longitud [] + longitud ys&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             longitud (conc xs ys) =&lt;br /&gt;
                             longitud xs + longitud ys ⟹&lt;br /&gt;
                             longitud (conc (a # xs) ys) =&lt;br /&gt;
                             longitud (a # xs) + longitud ys *) &lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (conc xs ys)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud xs + longitud ys&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = longitud (x # xs) + longitud ys&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Inducción correspondiente a la definición recursiva *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 14. Definir la función&lt;br /&gt;
     coge :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (coge n xs) es la lista de los n primeros elementos de xs. Por &lt;br /&gt;
  ejemplo, &lt;br /&gt;
     coge 2 [a,c,d,b,e] = [a,c]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun coge :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;coge n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge 0 xs           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge (Suc n) (x#xs) = x # (coge n xs)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;coge 2 [a,c,d,b,e] = [a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 15. Definir la función&lt;br /&gt;
     elimina :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (elimina n xs) es la lista obtenida eliminando los n primeros&lt;br /&gt;
  elementos de xs. Por ejemplo, &lt;br /&gt;
     elimina 2 [a,c,d,b,e] = [d,b,e]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun elimina :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;elimina n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;elimina 0 xs           = xs&amp;quot;&lt;br /&gt;
| &amp;quot;elimina (Suc n) (x#xs) = elimina n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;elimina 2 [a,c,d,b,e] = [d,b,e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  La definición coge genera el esquema de inducción coge.induct:&lt;br /&gt;
     ⟦⋀n. P n []; &lt;br /&gt;
      ⋀x xs. P 0 (x#xs); &lt;br /&gt;
      ⋀n x xs. P n xs ⟹ P (Suc n) (x#xs)⟧&lt;br /&gt;
     ⟹ P n x&lt;br /&gt;
&lt;br /&gt;
  Puede verse usando &amp;quot;thm coge.induct&amp;quot;. *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 16. (p. 35) Demostrar que &lt;br /&gt;
     conc (coge n xs) (elimina n xs) = xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  apply (induct rule: coge.induct) &lt;br /&gt;
      (*  1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
          2. ⋀v va. conc (coge 0 (v # va)) (elimina 0 (v # va)) =&lt;br /&gt;
                     v # va&lt;br /&gt;
          3. ⋀n x xs. conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
                       conc (coge (Suc n) (x # xs)) &lt;br /&gt;
                            (elimina (Suc n) (x # xs)) =&lt;br /&gt;
                       x # xs *)&lt;br /&gt;
    apply simp_all&lt;br /&gt;
      (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  by (induct rule: coge.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n x xs&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x#(conc (coge n xs) (elimina n xs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x#xs&amp;quot; using HI by simp  &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario sobre la demostración anterior:&lt;br /&gt;
  · (induct rule: coge.induct) indica que el método de demostración es&lt;br /&gt;
    por el esquema de inducción correspondiente a la definición de la&lt;br /&gt;
    función coge.&lt;br /&gt;
  · Se generan 3 subobjetivos:&lt;br /&gt;
    · 1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
    · 2. ⋀x xs. conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&lt;br /&gt;
    · 3. ⋀n x xs. &lt;br /&gt;
            conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
            conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = x#xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por casos *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 17. Definir la función&lt;br /&gt;
     esVacia :: &amp;#039;a list ⇒ bool&lt;br /&gt;
  tal que (esVacia xs) se verifica si xs es la lista vacía. Por ejemplo,&lt;br /&gt;
     esVacia []  = True&lt;br /&gt;
     esVacia [1] = False&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun esVacia :: &amp;quot;&amp;#039;a list ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;esVacia []     = True&amp;quot;&lt;br /&gt;
| &amp;quot;esVacia (x#xs) = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;esVacia []  = True&amp;quot;&lt;br /&gt;
value &amp;quot;esVacia [a] = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 18 (p. 39) . Demostrar que &lt;br /&gt;
     esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                    esVacia xs = esVacia (conc xs xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; es el método de demostración por casos según xs.&lt;br /&gt;
  · Se generan dos subobjetivos  correspondientes a los dos&lt;br /&gt;
    constructores de listas:&lt;br /&gt;
    · 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
    · 2. ⋀y ys. xs = y#ys ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica &amp;quot;usando la propiedad anterior&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &amp;quot;assume xs = []&amp;quot;&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &amp;quot;fix y ys assume xs = y#ys&amp;quot;&lt;br /&gt;
  · &amp;quot;thus&amp;quot; es una abreviatura de &amp;quot;then show&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración con el patrón sugerido es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case (Cons x xs)&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Heurística de generalización *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Heurística de generalización: Cuando se use demostración estructural,&lt;br /&gt;
  cuantificar universalmente las variables libres (o, equivalentemente,&lt;br /&gt;
  considerar las variables libres como variables arbitrarias). *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 19. Definir la función&lt;br /&gt;
     inversaAc :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversaAc xs) es a inversa de xs calculada usando&lt;br /&gt;
  acumuladores. Por ejemplo, &lt;br /&gt;
     inversaAc [a,c,b,e] = [e,b,c,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun inversaAcAux :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAcAux [] ys     = ys&amp;quot;&lt;br /&gt;
| &amp;quot;inversaAcAux (x#xs) ys = inversaAcAux xs (x#ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun inversaAc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAc xs = inversaAcAux xs []&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversaAc [a,c,b,e] = [e,b,c,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 20. (p. 44) Demostrar que &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  apply (induct xs arbitrary: ys) &lt;br /&gt;
     (* 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
        2. ⋀a xs ys.&lt;br /&gt;
              (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
              inversaAcAux (a # xs) ys = inversa (a # xs) @ ys *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  by (induct xs arbitrary: ys) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma inversaAcAux_es_inversa:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux [] ys = inversa [] @ ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs &lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; using HI by simp&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; by simp &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(induct xs arbitrary: ys)&amp;quot; es el método de demostración por&lt;br /&gt;
    inducción sobre xs usando ys como variable arbitraria.&lt;br /&gt;
  · Se generan dos subobjetivos:&lt;br /&gt;
    · 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
    · 2. ⋀a xs ys. (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
                    inversaAcAux (a # xs) ys = inversa (a # xs) @ ys&lt;br /&gt;
  · Dentro de una demostración se pueden incluir otras demostraciones.&lt;br /&gt;
  · Para demostrar la propiedad universal &amp;quot;⋀ys. P(ys)&amp;quot; se elige una&lt;br /&gt;
    lista arbitraria (con &amp;quot;fix ys&amp;quot;) y se demuestra &amp;quot;P(ys)&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 21. (p. 43) Demostrar que &lt;br /&gt;
     inversaAc xs = inversa xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  apply (simp add: inversaAcAux_es_inversa)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  by (simp add: inversaAcAux_es_inversa)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario de la demostración anterior:&lt;br /&gt;
  · &amp;quot;(simp add: inversaAcAux_es_inversa)&amp;quot; es el método de demostración&lt;br /&gt;
    por simplificación usando como regla de simplificación la propiedad&lt;br /&gt;
    inversaAcAux_es_inversa. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Demostración por inducción para funciones de orden superior *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 22. Definir la función&lt;br /&gt;
     sum :: nat list ⇒ nat&lt;br /&gt;
  tal que (sum xs) es la suma de los elementos de xs. Por ejemplo,&lt;br /&gt;
     sum [3,2,5] = 10&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun sum :: &amp;quot;nat list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sum []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;sum (x#xs) = x + sum xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sum [3,2,5] = 10&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 23. Definir la función&lt;br /&gt;
     map :: (&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&lt;br /&gt;
  tal que (map f xs) es la lista obtenida aplicando la función f a los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     map (λx. 2*x) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map (( * ) 2) [3::nat,2,5] = [6,4,10]&lt;br /&gt;
     map ((+) 2)   [3::nat,2,5] = [5,4,7]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun map :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&amp;quot; where&lt;br /&gt;
  &amp;quot;map f []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;map f (x#xs) = (f x) # map f xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;map (λx. 2*x) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map (( * ) 2) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
value &amp;quot;map ((+) 2)   [3::nat,2,5] = [5,4,7]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 24. (p. 45) Demostrar que &lt;br /&gt;
     sum (map (( * ) 2) xs) = 2 * (sum xs)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. sum (map (( * ) 2) []) = 2 * sum []&lt;br /&gt;
        2. ⋀a xs. sum (map (( * ) 2) xs) = 2 * sum xs ⟹&lt;br /&gt;
                  sum (map (( * ) 2) (a # xs)) = 2 * sum (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map (( * ) 2) []) = 2 * (sum [])&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map (( * ) 2) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map (( * ) 2) (a#xs)) = sum ((2*a)#(map (( * ) 2) xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 2*a + sum (map (( * ) 2) xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 2*a + 2*(sum xs)&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = 2*(a + sum xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 2*(sum (a#xs))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;sum (map (( * ) 2) (a#xs)) = 2*(sum (a#xs))&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 25. (p. 48) Demostrar que &lt;br /&gt;
     longitud (map f xs) = longitud xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. longitud (map f []) = longitud []&lt;br /&gt;
        2. ⋀a xs. longitud (map f xs) = longitud xs ⟹&lt;br /&gt;
                   longitud (map f (a # xs)) = longitud (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (map f xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud xs&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = longitud (a#xs)&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Referencias *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  · J.A. Alonso. &amp;quot;Razonamiento sobre programas&amp;quot; http://goo.gl/R06O3&lt;br /&gt;
  · G. Hutton. &amp;quot;Programming in Haskell&amp;quot;. Cap. 13 &amp;quot;Reasoning about&lt;br /&gt;
    programms&amp;quot;. &lt;br /&gt;
  · S. Thompson. &amp;quot;Haskell: the Craft of Functional Programming, 3rd&lt;br /&gt;
    Edition. Cap. 8 &amp;quot;Reasoning about programms&amp;quot;. &lt;br /&gt;
  · L. Paulson. &amp;quot;ML for the Working Programmer, 2nd Edition&amp;quot;. Cap. 6. &lt;br /&gt;
    &amp;quot;Reasoning about functional programs&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=620</id>
		<title>Razonamiento sobre programas en Isabelle/HOL</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Razonamiento_sobre_programas_en_Isabelle/HOL&amp;diff=620"/>
		<updated>2019-05-01T14:12:30Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* Tema 6: Razonamiento sobre programas *}&lt;br /&gt;
&lt;br /&gt;
theory T6_Razonamiento_sobre_programas&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  En este tema se demuestra con Isabelle las propiedades de los&lt;br /&gt;
  programas funcionales de tema 6 http://bit.ly/2Za6YWY&lt;br /&gt;
&lt;br /&gt;
  Para cada propiedades se presentan distintos tipos de demostraciones:&lt;br /&gt;
  automáticas, aplicativas y estructuradas. *} &lt;br /&gt;
&lt;br /&gt;
declare [[names_short]]&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento ecuacional *}&lt;br /&gt;
&lt;br /&gt;
text {* ----------------------------------------------------------------&lt;br /&gt;
  Ejemplo 1. Definir, por recursión, la función&lt;br /&gt;
     longitud :: &amp;#039;a list ⇒ nat&lt;br /&gt;
  tal que (longitud xs) es la longitud de la listas xs. Por ejemplo,&lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
fun longitud :: &amp;quot;&amp;#039;a list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;longitud []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;longitud (x#xs) = 1 + longitud xs&amp;quot;&lt;br /&gt;
   &lt;br /&gt;
value &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 2. Demostrar que &lt;br /&gt;
     longitud [a,c,d] = 3&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;longitud [a,c,d] = 3&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 3. Definir la función&lt;br /&gt;
     fun intercambia :: &amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&lt;br /&gt;
  tal que (intercambia p) es el par obtenido intercambiando las&lt;br /&gt;
  componentes del par p. Por ejemplo,&lt;br /&gt;
     intercambia (u,v) = (v,u)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun intercambia :: &amp;quot;&amp;#039;a × &amp;#039;b ⇒ &amp;#039;b × &amp;#039;a&amp;quot; where&lt;br /&gt;
  &amp;quot;intercambia (x,y) = (y,x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;intercambia (u,v) = (v,u)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La definición de la función intercambia genera una regla de&lt;br /&gt;
  simplificación&lt;br /&gt;
  · intercambia.simps: intercambia (x,y) = (y,x)&lt;br /&gt;
  &lt;br /&gt;
  Se puede ver con &lt;br /&gt;
  · thm intercambia.simps &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
thm intercambia.simps&lt;br /&gt;
(* da intercambia (?x, ?y) = (?y, ?x) *)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 4. (p.6) Demostrar que &lt;br /&gt;
     intercambia (intercambia (x,y)) = (x,y)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by simp &lt;br /&gt;
&lt;br /&gt;
(* Demostración automática 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  by (simp only: intercambia.simps)&lt;br /&gt;
&lt;br /&gt;
(* Demostración aplicativa *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
  apply (simp only: intercambia.simps)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 1 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  by simp&lt;br /&gt;
  also have &amp;quot;... = (x,y)&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* Demostración declarativa 2 *)&lt;br /&gt;
lemma &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;intercambia (intercambia (x,y)) = intercambia (y,x)&amp;quot;  &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  also have &amp;quot;... = (x,y)&amp;quot; &lt;br /&gt;
    by (simp only: intercambia.simps)&lt;br /&gt;
  finally show &amp;quot;intercambia (intercambia (x,y)) = (x,y)&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Notas sobre el lenguaje: En la demostración anterior se ha usado&lt;br /&gt;
  · &amp;quot;proof&amp;quot; para iniciar la prueba,&lt;br /&gt;
  · &amp;quot;-&amp;quot; (después de &amp;quot;proof&amp;quot;) para no usar el método por defecto,&lt;br /&gt;
  · &amp;quot;have&amp;quot; para establecer un paso,&lt;br /&gt;
  · &amp;quot;by (simp only: intercambia.simps)&amp;quot; para indicar que sólo se usa&lt;br /&gt;
    como regla de escritura la correspondiente a la definición de&lt;br /&gt;
    intercambia,&lt;br /&gt;
  · &amp;quot;also&amp;quot; para encadenar pasos ecuacionales,&lt;br /&gt;
  · &amp;quot;...&amp;quot; para representar la derecha de la igualdad anterior en un&lt;br /&gt;
    razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;finally&amp;quot; para indicar el último pasa de un razonamiento ecuacional,&lt;br /&gt;
  · &amp;quot;show&amp;quot; para establecer la conclusión.&lt;br /&gt;
  · &amp;quot;by simp&amp;quot; para indicar el método de demostración por simplificación y &lt;br /&gt;
  · &amp;quot;qed&amp;quot; para terminar la pruebas,&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Nota: La diferencia entre las dos demostraciones es que en los dos&lt;br /&gt;
  primeros pasos no se explicita la regla de simplificación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 5. Definir, por recursión, la función&lt;br /&gt;
     inversa :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversa xs) es la lista obtenida invirtiendo el orden de los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     inversa [a,d,c] = [c,d,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun inversa :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversa []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;inversa (x#xs) = inversa xs @ [x]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversa [a,d,c] = [c,d,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 6. (p. 9) Demostrar que &lt;br /&gt;
     inversa [x] = [x]&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  by simp&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En la demostración anterior se usaron las siguientes reglas:&lt;br /&gt;
  · inversa.simps(1): inversa [] = []&lt;br /&gt;
  · inversa.simps(2): inversa (x#xs) = inversa xs @ [x]&lt;br /&gt;
  · append_Nil:       [] @ ys = ys&lt;br /&gt;
  Vamos a explicitar su aplicación.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa detallada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
  apply (simp only: inversa.simps(2)) (* inversa [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: inversa.simps(1)) (* [] @ [x] = [x] *)&lt;br /&gt;
  apply (simp only: append_Nil)       (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = (inversa []) @ [x]&amp;quot; by (simp only: inversa.simps(2))&lt;br /&gt;
  also have &amp;quot;... = [] @ [x]&amp;quot; by (simp only: inversa.simps(1))&lt;br /&gt;
  also have &amp;quot;... = [x]&amp;quot; by (simp only: append_Nil) &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
(* La demostración declarativa simplificada es *)&lt;br /&gt;
lemma &amp;quot;inversa [x] = [x]&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;inversa [x] = inversa (x#[])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = (inversa []) @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = [] @ [x]&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = [x]&amp;quot; by simp &lt;br /&gt;
  finally show &amp;quot;inversa [x] = [x]&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por inducción sobre los naturales *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  [Principio de inducción sobre los naturales] Para demostrar una&lt;br /&gt;
  propiedad P para todos los números naturales basta probar que el 0&lt;br /&gt;
  tiene la propiedad P y que si n tiene la propiedad P, entonces n+1&lt;br /&gt;
  también la tiene.  &lt;br /&gt;
     ⟦P 0; ⋀n. P n ⟹ P (Suc n)⟧ ⟹ P m&lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre los naturales está&lt;br /&gt;
  formalizado en el teorema nat.induct y puede verse con&lt;br /&gt;
     thm nat.induct&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 7. Definir la función&lt;br /&gt;
     repite :: nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (repite n x) es la lista formada por n copias del elemento&lt;br /&gt;
  x. Por ejemplo, &lt;br /&gt;
     repite 3 a = [a,a,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun repite :: &amp;quot;nat ⇒ &amp;#039;a ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;repite 0 x       = []&amp;quot;&lt;br /&gt;
| &amp;quot;repite (Suc n) x = x # (repite n x)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;repite 3 a = [a,a,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 8. (p. 18) Demostrar que &lt;br /&gt;
     longitud (repite n x) = n&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp      (* 1. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
  apply simp       (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa con simp_all es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  apply (induct n) (* 1. longitud (repite 0 x) = 0&lt;br /&gt;
                      2. ⋀n. longitud (repite n x) = n ⟹&lt;br /&gt;
                         longitud (repite (Suc n) x) = Suc n *)&lt;br /&gt;
   apply simp_all  (* No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  by (induct n) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
proof (induct n)&lt;br /&gt;
  show &amp;quot;longitud (repite 0 x) = 0&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix n&lt;br /&gt;
  assume HI: &amp;quot;longitud (repite n x) = n&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (repite (Suc n) x) = longitud (x # (repite n x))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (repite n x)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + n&amp;quot; using HI by simp&lt;br /&gt;
  finally show &amp;quot;longitud (repite (Suc n) x) = Suc n&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · A la derecha de proof se indica el método de la demostración.&lt;br /&gt;
  · (induct n) indica que la demostración se hará por inducción en n.&lt;br /&gt;
  · Se generan dos subobjetivos correspondientes a la base y el paso de&lt;br /&gt;
    inducción:&lt;br /&gt;
    1. longitud (repite 0 x) = 0&lt;br /&gt;
    2. ⋀n. longitud (repite n x) = n ⟹ &lt;br /&gt;
            longitud (repite (Suc n) x) = Suc n&lt;br /&gt;
    donde ⋀n se lee &amp;quot;para todo n&amp;quot;.  &lt;br /&gt;
  · &amp;quot;next&amp;quot; indica el siguiente subobjetivo.&lt;br /&gt;
  · &amp;quot;fix n&amp;quot; indica &amp;quot;sea n un número natural cualquiera&amp;quot;&lt;br /&gt;
  · assume HI: &amp;quot;longitud (repite n x) = n&amp;quot; indica «supongamos que &lt;br /&gt;
    &amp;quot;longitud (repite n x) = n&amp;quot; y sea HI la etiqueta de este supuesto».&lt;br /&gt;
  · &amp;quot;using HI&amp;quot; usando la propiedad etiquetada con HI. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por inducción sobre listas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Para demostrar una propiedad para todas las listas basta demostrar&lt;br /&gt;
  que la lista vacía tiene la propiedad y que al añadir un elemento a&lt;br /&gt;
  una lista que tiene la propiedad se obtiene otra lista que también&lt;br /&gt;
  tiene la propiedad. &lt;br /&gt;
&lt;br /&gt;
  En Isabelle el principio de inducción sobre listas está formalizado&lt;br /&gt;
  mediante el teorema list.induct &lt;br /&gt;
     ⟦P []; &lt;br /&gt;
      ⋀x xs. P xs ⟹ P (x#xs)⟧ &lt;br /&gt;
     ⟹ P xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 9. Definir la función&lt;br /&gt;
     conc :: &amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (conc xs ys) es la concatención de las listas xs e ys. Por&lt;br /&gt;
  ejemplo, &lt;br /&gt;
     conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun conc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;conc []     ys = ys&amp;quot;&lt;br /&gt;
| &amp;quot;conc (x#xs) ys = x # (conc xs ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;conc [a,d] [b,d,a,c] = [a,d,b,d,a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 10. (p. 24) Demostrar que &lt;br /&gt;
     conc xs (conc ys zs) = (conc xs ys) zs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  apply (induct xs) (*  1. conc [] (conc ys zs) = conc (conc [] ys) zs&lt;br /&gt;
                        2. ⋀a xs.&lt;br /&gt;
                              conc xs (conc ys zs) =&lt;br /&gt;
                              conc (conc xs ys) zs ⟹&lt;br /&gt;
                              conc (a # xs) (conc ys zs) =&lt;br /&gt;
                              conc (conc (a # xs) ys) zs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] (conc ys zs) = conc (conc [] ys) zs&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs (conc ys zs) = conc (conc xs ys) zs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) (conc ys zs) = x # (conc xs (conc ys zs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x # (conc (conc xs ys) zs)&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = conc (conc (x # xs) ys) zs&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) (conc ys zs) = conc (conc (x # xs) ys) zs&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 11. Refutar que &lt;br /&gt;
     conc xs ys = conc ys xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;conc xs ys = conc ys xs&amp;quot;&lt;br /&gt;
  quickcheck&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Encuentra el contraejemplo, &lt;br /&gt;
  xs = [a2]&lt;br /&gt;
  ys = [a1] *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 12. (p. 28) Demostrar que &lt;br /&gt;
     conc xs [] = xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. conc [] [] = []&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             conc xs [] = xs ⟹&lt;br /&gt;
                             conc (a # xs) [] = a # xs *)&lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;conc xs [] = xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;conc [] [] = []&amp;quot; by simp&lt;br /&gt;
next &lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;conc xs [] = xs&amp;quot; &lt;br /&gt;
  have &amp;quot;conc (x # xs) [] = x # (conc xs [])&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x # xs&amp;quot; using HI by simp&lt;br /&gt;
  finally show &amp;quot;conc (x # xs) [] = x # xs&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 13. (p. 30) Demostrar que &lt;br /&gt;
     longitud (conc xs ys) = longitud xs + longitud ys&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  apply (induct xs) (* 1. longitud (conc [] ys) =&lt;br /&gt;
                          longitud [] + longitud ys&lt;br /&gt;
                       2. ⋀a xs.&lt;br /&gt;
                             longitud (conc xs ys) =&lt;br /&gt;
                             longitud xs + longitud ys ⟹&lt;br /&gt;
                             longitud (conc (a # xs) ys) =&lt;br /&gt;
                             longitud (a # xs) + longitud ys *) &lt;br /&gt;
   apply simp_all   (* No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (conc [] ys) = longitud [] + longitud ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (conc xs ys) = longitud xs + longitud ys&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (conc (x # xs) ys) = longitud (x # (conc xs ys))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (conc xs ys)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud xs + longitud ys&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = longitud (x # xs) + longitud ys&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;longitud (conc (x # xs) ys) = &lt;br /&gt;
                longitud (x # xs) + longitud ys&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Inducción correspondiente a la definición recursiva *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 14. Definir la función&lt;br /&gt;
     coge :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (coge n xs) es la lista de los n primeros elementos de xs. Por &lt;br /&gt;
  ejemplo, &lt;br /&gt;
     coge 2 [a,c,d,b,e] = [a,c]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun coge :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;coge n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge 0 xs           = []&amp;quot;&lt;br /&gt;
| &amp;quot;coge (Suc n) (x#xs) = x # (coge n xs)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;coge 2 [a,c,d,b,e] = [a,c]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 15. Definir la función&lt;br /&gt;
     elimina :: nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (elimina n xs) es la lista obtenida eliminando los n primeros&lt;br /&gt;
  elementos de xs. Por ejemplo, &lt;br /&gt;
     elimina 2 [a,c,d,b,e] = [d,b,e]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun elimina :: &amp;quot;nat ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;elimina n []           = []&amp;quot;&lt;br /&gt;
| &amp;quot;elimina 0 xs           = xs&amp;quot;&lt;br /&gt;
| &amp;quot;elimina (Suc n) (x#xs) = elimina n xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;elimina 2 [a,c,d,b,e] = [d,b,e]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  La definición coge genera el esquema de inducción coge.induct:&lt;br /&gt;
     ⟦⋀n. P n []; &lt;br /&gt;
      ⋀x xs. P 0 (x#xs); &lt;br /&gt;
      ⋀n x xs. P n xs ⟹ P (Suc n) (x#xs)⟧&lt;br /&gt;
     ⟹ P n x&lt;br /&gt;
&lt;br /&gt;
  Puede verse usando &amp;quot;thm coge.induct&amp;quot;. *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 16. (p. 35) Demostrar que &lt;br /&gt;
     conc (coge n xs) (elimina n xs) = xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  apply (induct rule: coge.induct) &lt;br /&gt;
      (*  1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
          2. ⋀v va. conc (coge 0 (v # va)) (elimina 0 (v # va)) =&lt;br /&gt;
                     v # va&lt;br /&gt;
          3. ⋀n x xs. conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
                       conc (coge (Suc n) (x # xs)) &lt;br /&gt;
                            (elimina (Suc n) (x # xs)) =&lt;br /&gt;
                       x # xs *)&lt;br /&gt;
    apply simp_all&lt;br /&gt;
      (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  by (induct rule: coge.induct) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
proof (induct rule: coge.induct)&lt;br /&gt;
  fix n&lt;br /&gt;
  show &amp;quot;conc (coge n []) (elimina n []) = []&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix x xs&lt;br /&gt;
  show &amp;quot;conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix n x xs&lt;br /&gt;
  assume HI: &amp;quot;conc (coge n xs) (elimina n xs) = xs&amp;quot;&lt;br /&gt;
  have &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
        conc (x#(coge n xs)) (elimina n xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x#(conc (coge n xs) (elimina n xs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = x#xs&amp;quot; using HI by simp  &lt;br /&gt;
  finally show &amp;quot;conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = &lt;br /&gt;
                x#xs&amp;quot;&lt;br /&gt;
    by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario sobre la demostración anterior:&lt;br /&gt;
  · (induct rule: coge.induct) indica que el método de demostración es&lt;br /&gt;
    por el esquema de inducción correspondiente a la definición de la&lt;br /&gt;
    función coge.&lt;br /&gt;
  · Se generan 3 subobjetivos:&lt;br /&gt;
    · 1. ⋀n. conc (coge n []) (elimina n []) = []&lt;br /&gt;
    · 2. ⋀x xs. conc (coge 0 (x#xs)) (elimina 0 (x#xs)) = x#xs&lt;br /&gt;
    · 3. ⋀n x xs. &lt;br /&gt;
            conc (coge n xs) (elimina n xs) = xs ⟹&lt;br /&gt;
            conc (coge (Suc n) (x#xs)) (elimina (Suc n) (x#xs)) = x#xs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Razonamiento por casos *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 17. Definir la función&lt;br /&gt;
     esVacia :: &amp;#039;a list ⇒ bool&lt;br /&gt;
  tal que (esVacia xs) se verifica si xs es la lista vacía. Por ejemplo,&lt;br /&gt;
     esVacia []  = True&lt;br /&gt;
     esVacia [1] = False&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun esVacia :: &amp;quot;&amp;#039;a list ⇒ bool&amp;quot; where&lt;br /&gt;
  &amp;quot;esVacia []     = True&amp;quot;&lt;br /&gt;
| &amp;quot;esVacia (x#xs) = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;esVacia []  = True&amp;quot;&lt;br /&gt;
value &amp;quot;esVacia [a] = False&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 18 (p. 39) . Demostrar que &lt;br /&gt;
     esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  apply (cases xs) &lt;br /&gt;
     (* 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
        2. ⋀a list. xs = a # list ⟹&lt;br /&gt;
                    esVacia xs = esVacia (conc xs xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
  by (cases xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  assume &amp;quot;xs = []&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix y ys&lt;br /&gt;
  assume &amp;quot;xs = y#ys&amp;quot;&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(cases xs)&amp;quot; es el método de demostración por casos según xs.&lt;br /&gt;
  · Se generan dos subobjetivos  correspondientes a los dos&lt;br /&gt;
    constructores de listas:&lt;br /&gt;
    · 1. xs = [] ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
    · 2. ⋀y ys. xs = y#ys ⟹ esVacia xs = esVacia (conc xs xs)&lt;br /&gt;
  · &amp;quot;then&amp;quot; indica &amp;quot;usando la propiedad anterior&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada simplificada es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  case Cons&lt;br /&gt;
  then show &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;case Nil&amp;quot; es una abreviatura de &amp;quot;assume xs = []&amp;quot;&lt;br /&gt;
  · &amp;quot;case Cons&amp;quot; es una abreviatura de &amp;quot;fix y ys assume xs = y#ys&amp;quot;&lt;br /&gt;
  · &amp;quot;thus&amp;quot; es una abreviatura de &amp;quot;then show&amp;quot;.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
(* La demostración con el patrón sugerido es *)&lt;br /&gt;
lemma &amp;quot;esVacia xs = esVacia (conc xs xs)&amp;quot;&lt;br /&gt;
proof (cases xs)&lt;br /&gt;
  case Nil&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
next&lt;br /&gt;
  case (Cons x xs)&lt;br /&gt;
  then show ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Heurística de generalización *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Heurística de generalización: Cuando se use demostración estructural,&lt;br /&gt;
  cuantificar universalmente las variables libres (o, equivalentemente,&lt;br /&gt;
  considerar las variables libres como variables arbitrarias). *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 19. Definir la función&lt;br /&gt;
     inversaAc :: &amp;#039;a list ⇒ &amp;#039;a list&lt;br /&gt;
  tal que (inversaAc xs) es a inversa de xs calculada usando&lt;br /&gt;
  acumuladores. Por ejemplo, &lt;br /&gt;
     inversaAc [a,c,b,e] = [e,b,c,a]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun inversaAcAux :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAcAux [] ys     = ys&amp;quot;&lt;br /&gt;
| &amp;quot;inversaAcAux (x#xs) ys = inversaAcAux xs (x#ys)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
fun inversaAc :: &amp;quot;&amp;#039;a list ⇒ &amp;#039;a list&amp;quot; where&lt;br /&gt;
  &amp;quot;inversaAc xs = inversaAcAux xs []&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;inversaAc [a,c,b,e] = [e,b,c,a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 20. (p. 44) Demostrar que &lt;br /&gt;
     inversaAcAux xs ys = (inversa xs) @ ys&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  apply (induct xs arbitrary: ys) &lt;br /&gt;
     (* 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
        2. ⋀a xs ys.&lt;br /&gt;
              (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
              inversaAcAux (a # xs) ys = inversa (a # xs) @ ys *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;inversaAcAux xs ys = (inversa xs)@ys&amp;quot;&lt;br /&gt;
  by (induct xs arbitrary: ys) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma inversaAcAux_es_inversa:&lt;br /&gt;
  &amp;quot;inversaAcAux xs ys = (inversa xs) @ ys&amp;quot;&lt;br /&gt;
proof (induct xs arbitrary: ys)&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux [] ys = inversa [] @ ys&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs &lt;br /&gt;
  assume HI: &amp;quot;⋀ys. inversaAcAux xs ys = inversa xs@ys&amp;quot;&lt;br /&gt;
  show &amp;quot;⋀ys. inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot;&lt;br /&gt;
  proof -&lt;br /&gt;
    fix ys&lt;br /&gt;
    have &amp;quot;inversaAcAux (a#xs) ys = inversaAcAux xs (a#ys)&amp;quot; by simp&lt;br /&gt;
    also have &amp;quot;… = inversa xs@(a#ys)&amp;quot; using HI by simp&lt;br /&gt;
    also have &amp;quot;… = inversa (a#xs)@ys&amp;quot; by simp &lt;br /&gt;
    finally show &amp;quot;inversaAcAux (a#xs) ys = inversa (a#xs)@ys&amp;quot; by simp&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentarios sobre la demostración anterior:&lt;br /&gt;
  · &amp;quot;(induct xs arbitrary: ys)&amp;quot; es el método de demostración por&lt;br /&gt;
    inducción sobre xs usando ys como variable arbitraria.&lt;br /&gt;
  · Se generan dos subobjetivos:&lt;br /&gt;
    · 1. ⋀ys. inversaAcAux [] ys = inversa [] @ ys&lt;br /&gt;
    · 2. ⋀a xs ys. (⋀ys. inversaAcAux xs ys = inversa xs @ ys) ⟹&lt;br /&gt;
                    inversaAcAux (a # xs) ys = inversa (a # xs) @ ys&lt;br /&gt;
  · Dentro de una demostración se pueden incluir otras demostraciones.&lt;br /&gt;
  · Para demostrar la propiedad universal &amp;quot;⋀ys. P(ys)&amp;quot; se elige una&lt;br /&gt;
    lista arbitraria (con &amp;quot;fix ys&amp;quot;) y se demuestra &amp;quot;P(ys)&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 21. (p. 43) Demostrar que &lt;br /&gt;
     inversaAc xs = inversa xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  apply (simp add: inversaAcAux_es_inversa)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
corollary &amp;quot;inversaAc xs = inversa xs&amp;quot;&lt;br /&gt;
  by (simp add: inversaAcAux_es_inversa)&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Comentario de la demostración anterior:&lt;br /&gt;
  · &amp;quot;(simp add: inversaAcAux_es_inversa)&amp;quot; es el método de demostración&lt;br /&gt;
    por simplificación usando como regla de simplificación la propiedad&lt;br /&gt;
    inversaAcAux_es_inversa. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Demostración por inducción para funciones de orden superior *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 22. Definir la función&lt;br /&gt;
     sum :: nat list ⇒ nat&lt;br /&gt;
  tal que (sum xs) es la suma de los elementos de xs. Por ejemplo,&lt;br /&gt;
     sum [3,2,5] = 10&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun sum :: &amp;quot;nat list ⇒ nat&amp;quot; where&lt;br /&gt;
  &amp;quot;sum []     = 0&amp;quot;&lt;br /&gt;
| &amp;quot;sum (x#xs) = x + sum xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;sum [3,2,5] = 10&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 23. Definir la función&lt;br /&gt;
     map :: (&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&lt;br /&gt;
  tal que (map f xs) es la lista obtenida aplicando la función f a los&lt;br /&gt;
  elementos de xs. Por ejemplo,&lt;br /&gt;
     map (λx. 2*x) [3,2,5] = [6,4,10]&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
fun map :: &amp;quot;(&amp;#039;a ⇒ &amp;#039;b) ⇒ &amp;#039;a list ⇒ &amp;#039;b list&amp;quot; where&lt;br /&gt;
  &amp;quot;map f []     = []&amp;quot;&lt;br /&gt;
| &amp;quot;map f (x#xs) = (f x) # map f xs&amp;quot;&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;map (λx. 2*x) [3::nat,2,5] = [6,4,10]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 24. (p. 45) Demostrar que &lt;br /&gt;
     sum (map (λx. 2*x) xs) = 2 * (sum xs)&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;sum (map (λx. 2*x) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. sum (map (( * ) 2) []) = 2 * sum []&lt;br /&gt;
        2. ⋀a xs. sum (map (( * ) 2) xs) = 2 * sum xs ⟹&lt;br /&gt;
                  sum (map (( * ) 2) (a # xs)) = 2 * sum (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;sum (map (λx. 2*x) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;sum (map (λx. 2*x) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;sum (map (λx. 2*x) []) = 2 * (sum [])&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;sum (map (λx. 2*x) xs) = 2 * (sum xs)&amp;quot;&lt;br /&gt;
  have &amp;quot;sum (map (λx. 2*x) (a#xs)) = sum ((2*a)#(map (λx. 2*x) xs))&amp;quot; &lt;br /&gt;
    by simp&lt;br /&gt;
  also have &amp;quot;... = 2*a + sum (map (λx. 2*x) xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 2*a + 2*(sum xs)&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = 2*(a + sum xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 2*(sum (a#xs))&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;sum (map (λx. 2*x) (a#xs)) = 2*(sum (a#xs))&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejemplo 25. (p. 48) Demostrar que &lt;br /&gt;
     longitud (map f xs) = longitud xs&lt;br /&gt;
  ------------------------------------------------------------------- *}&lt;br /&gt;
&lt;br /&gt;
(* La demostración aplicativa es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  apply (induct xs) &lt;br /&gt;
     (* 1. longitud (map f []) = longitud []&lt;br /&gt;
        2. ⋀a xs. longitud (map f xs) = longitud xs ⟹&lt;br /&gt;
                   longitud (map f (a # xs)) = longitud (a # xs) *)&lt;br /&gt;
   apply simp_all&lt;br /&gt;
     (* No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
(* La demostración automática es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  by (induct xs) simp_all&lt;br /&gt;
&lt;br /&gt;
(* La demostración estructurada es *)&lt;br /&gt;
lemma &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
proof (induct xs)&lt;br /&gt;
  show &amp;quot;longitud (map f []) = longitud []&amp;quot; by simp&lt;br /&gt;
next&lt;br /&gt;
  fix a xs&lt;br /&gt;
  assume HI: &amp;quot;longitud (map f xs) = longitud xs&amp;quot;&lt;br /&gt;
  have &amp;quot;longitud (map f (a#xs)) = longitud (f a # (map f xs))&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud (map f xs)&amp;quot; by simp&lt;br /&gt;
  also have &amp;quot;... = 1 + longitud xs&amp;quot; using HI by simp&lt;br /&gt;
  also have &amp;quot;... = longitud (a#xs)&amp;quot; by simp&lt;br /&gt;
  finally show &amp;quot;longitud (map f (a#xs)) = longitud (a#xs)&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Referencias *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  · J.A. Alonso. &amp;quot;Razonamiento sobre programas&amp;quot; http://goo.gl/R06O3&lt;br /&gt;
  · G. Hutton. &amp;quot;Programming in Haskell&amp;quot;. Cap. 13 &amp;quot;Reasoning about&lt;br /&gt;
    programms&amp;quot;. &lt;br /&gt;
  · S. Thompson. &amp;quot;Haskell: the Craft of Functional Programming, 3rd&lt;br /&gt;
    Edition. Cap. 8 &amp;quot;Reasoning about programms&amp;quot;. &lt;br /&gt;
  · L. Paulson. &amp;quot;ML for the Working Programmer, 2nd Edition&amp;quot;. Cap. 6. &lt;br /&gt;
    &amp;quot;Reasoning about functional programs&amp;quot;. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_7b&amp;diff=580</id>
		<title>Sol 7b</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_7b&amp;diff=580"/>
		<updated>2019-04-21T09:26:59Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
theory R7b&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Demostrar o refutar los siguientes lemas usando sólo las reglas&lt;br /&gt;
  básicas de deducción natural de la lógica proposicional, de los&lt;br /&gt;
  cuantificadores y de la igualdad y los métodos rule, erule, frule, drule y assumption.  &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_middel:(¬P ∨ P) &lt;br /&gt;
&lt;br /&gt;
  · allI:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allE:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ a: = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. Demostrar&lt;br /&gt;
       ∀x. P x ⟶ Q x ⊢ (∀x. P x) ⟶ (∀x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej1a: &amp;quot;∀x. P x ⟶ Q x ⟹ (∀x. P x) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦∀x. P x ⟶ Q x; ∀x. P x⟧ ⟹ ∀x. Q x*)&lt;br /&gt;
  apply (rule allI)  (* ⋀x. ⟦∀x. P x ⟶ Q x; ∀x. P x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule allE) (* ⋀x. ⟦∀x. P x; P (?x4 x) ⟶ Q (?x4 x)⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule allE) (* ⋀x. ⟦P (?x4 x) ⟶ Q (?x4 x); P (?x6 x)⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule mp)   (* ⋀x. P (?x6 x) ⟹ P x *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej1b: &amp;quot;∀x. P x ⟶ Q x ⟹ (∀x. P x) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦∀x. P x ⟶ Q x; ∀x. P x⟧ ⟹ ∀x. Q x *)&lt;br /&gt;
  apply (rule allI)         (* ⋀x. ⟦∀x. P x ⟶ Q x; ∀x. P x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x. ⟦∀x. P x; P x ⟶ Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x. ⟦P x ⟶ Q x; P x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule mp)              (* ⋀x. P x ⟹ P x *)&lt;br /&gt;
  apply assumption              (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej1c: &amp;quot;∀x. P x ⟶ Q x ⟹ (∀x. P x) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦∀x. P x ⟶ Q x; ∀x. P x⟧ ⟹ ∀x. Q x *)&lt;br /&gt;
  apply (rule allI)         (* ⋀x. ⟦∀x. P x ⟶ Q x; ∀x. P x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule_tac x=x in allE)+ (* ⋀x. ⟦P x ⟶ Q x; P x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule mp)               (* ⋀x. P x ⟹ P x *)&lt;br /&gt;
  apply assumption               (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. Demostrar&lt;br /&gt;
       ∃x. ¬(P x) ⊢ ¬(∀x. P x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej2: &amp;quot;∃x. ¬(P x) ⟹ ¬(∀x. P x)&amp;quot;&lt;br /&gt;
  apply (rule notI)             (* ⟦∃x. ¬ P x; ∀x. P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)             (* ⋀x. ⟦∀x. P x; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x. ⟦¬ P x; P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)            (* ⋀x. P x ⟹ P x *) &lt;br /&gt;
  apply assumption              (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3. Demostrar&lt;br /&gt;
       ∀x. P x ⊢ ∀y. P y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej3: &amp;quot;∀x. P x ⟹ ∀y. P y&amp;quot;&lt;br /&gt;
  apply (rule allI)             (* ⋀y. ∀x. P x ⟹ P y *)&lt;br /&gt;
  apply (erule_tac x=y in allE) (* ⋀y. P y ⟹ P y*)&lt;br /&gt;
  apply assumption              (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. Demostrar&lt;br /&gt;
       ∀x. P x ⟶ Q x ⊢ (∀x. ¬(Q x)) ⟶ (∀x. ¬ (P x))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej4: &amp;quot;∀x. P x ⟶ Q x ⟹ (∀x. ¬(Q x)) ⟶ (∀x. ¬(P x))&amp;quot;&lt;br /&gt;
  apply (rule impI)    (* ⟦∀x. P x ⟶ Q x; ∀x. ¬ Q x⟧ ⟹ ∀x. ¬ P x *)&lt;br /&gt;
  apply (rule allI)    (* ⋀x. ⟦∀x. P x ⟶ Q x; ∀x. ¬ Q x⟧ ⟹ ¬ P x *)&lt;br /&gt;
  apply (erule_tac x=x in allE)+ &lt;br /&gt;
                       (* ⋀x. ⟦P x ⟶ Q x; ¬ Q x⟧ ⟹ ¬ P x *)&lt;br /&gt;
  apply (rule notI)    (* ⋀x. ⟦P x ⟶ Q x; ¬ Q x; P x⟧ ⟹ False *) &lt;br /&gt;
  apply (erule impE)   (* ⋀x. ⟦¬ Q x; P x⟧ ⟹ P x&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; P x; Q x⟧ ⟹ False *) &lt;br /&gt;
   apply assumption    (* ⋀x. ⟦¬ Q x; P x; Q x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)   (* ⋀x. ⟦P x; Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 5. Demostrar&lt;br /&gt;
       ∀x. P x  ⟶ ¬(Q x) ⊢ ¬(∃x. P x ∧ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej5: &amp;quot;∀x. P x  ⟶ ¬(Q x) ⟹ ¬(∃x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
  apply (rule notI)   &lt;br /&gt;
                 (* ⟦∀x. P x ⟶ ¬ Q x; ∃x. P x ∧ Q x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)   &lt;br /&gt;
                 (* ⋀x. ⟦∀x. P x ⟶ ¬ Q x; P x ∧ Q x⟧ ⟹ False *)&lt;br /&gt;
  apply (frule conjunct1)&lt;br /&gt;
                 (* ⋀x. ⟦∀x. P x ⟶ ¬ Q x; P x ∧ Q x; P x⟧ ⟹ False*)&lt;br /&gt;
  apply (erule_tac x=x in allE)  &lt;br /&gt;
                 (* ⋀x. ⟦P x ∧ Q x; P x; P x ⟶ ¬ Q x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule impE)&lt;br /&gt;
                 (* ⋀x. ⟦P x ∧ Q x; P x⟧ ⟹ P x&lt;br /&gt;
                    ⋀x. ⟦P x ∧ Q x; P x; ¬ Q x⟧ ⟹ False *)&lt;br /&gt;
   apply assumption&lt;br /&gt;
                 (* ⋀x. ⟦P x ∧ Q x; P x; ¬ Q x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
                 (* ⋀x. ⟦P x ∧ Q x; P x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
                 (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 6. Demostrar&lt;br /&gt;
       ∀x y. P x y ⊢ ∀u v. P u v&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej6a: &amp;quot;∀x y. P x y ⟹ ∀u v. P u v&amp;quot;&lt;br /&gt;
  apply (rule allI)              (* ⋀u. ∀x y. P x y ⟹ ∀v. P u v *)&lt;br /&gt;
  apply (rule allI)              (* ⋀u v. ∀x y. P x y ⟹ P u v *) &lt;br /&gt;
  apply (erule_tac x=u in allE)  (* ⋀u v. ∀y. P u y ⟹ P u v *)&lt;br /&gt;
  apply (erule_tac x=v in allE)  (* ⋀u v. P u v ⟹ P u v *)&lt;br /&gt;
  apply assumption               (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6b: &amp;quot;∀x y. P x y ⟹ ∀u v. P u v&amp;quot;&lt;br /&gt;
  apply (rule allI)+    (* ⋀u v. ∀x y. P x y ⟹ P u v *)&lt;br /&gt;
  apply (erule allE)+   (* ⋀u v. P (?x4 u v) (?y6 u v) ⟹ P u v *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 7. Demostrar&lt;br /&gt;
       ∃x y. P x y ⟹ ∃u v. P u v&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej7a: &amp;quot;∃x y. P x y ⟹ ∃u v. P u v&amp;quot;&lt;br /&gt;
  apply (erule exE)            (* ⋀x. ∃y. P x y ⟹ ∃u v. P u v *)&lt;br /&gt;
  apply (erule exE)            (* ⋀x y. P x y ⟹ ∃u v. P u v*)&lt;br /&gt;
  apply (rule_tac x=x in exI)  (* ⋀x y. P x y ⟹ ∃v. P x v *)&lt;br /&gt;
  apply (rule_tac x=y in exI)  (* ⋀x y. P x y ⟹ P x y *)&lt;br /&gt;
  apply assumption             (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7b: &amp;quot;∃x y. P x y ⟹ ∃u v. P u v&amp;quot;&lt;br /&gt;
  apply (erule exE)+  (* ⋀x y. P x y ⟹ ∃u v. P u v *)&lt;br /&gt;
  apply (rule exI)+   (* ⋀x y. P x y ⟹ P (?u4 x y) (?v6 x y) *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 8. Demostrar&lt;br /&gt;
       ∃x. ∀y. P x y ⊢ ∀y. ∃x. P x y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej8a: &amp;quot;∃x. ∀y. P x y ⟹ ∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
  apply (rule allI)              (* ⋀y. ∃x. ∀y. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule exE)              (* ⋀y x. ∀y. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule_tac x=y in allE)  (* ⋀y x. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule_tac x=x in exI)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8b: &amp;quot;∃x. ∀y. P x y ⟹ ∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* ⋀y. ∃x. ∀y. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule exE)   (* ⋀y x. ∀y. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule allE)  (* ⋀y x. P x (?y4 y x) ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule exI)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 9. Demostrar&lt;br /&gt;
       ∃x. P a ⟶ Q x ⊢ P a ⟶ (∃x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej9: &amp;quot;∃x. P a ⟶ Q x ⟹ P a ⟶ (∃x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦∃x. P a ⟶ Q x; P a⟧ ⟹ ∃x. Q x *)&lt;br /&gt;
  apply (erule exE)         (* ⋀x. ⟦P a; P a ⟶ Q x⟧ ⟹ ∃x. Q x *)&lt;br /&gt;
  apply (rule_tac x=x in exI)   (* ⋀x. ⟦P a; P a ⟶ Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule impE)            (* ⋀x. P a ⟹ P a&lt;br /&gt;
                                   ⋀x. ⟦P a; Q x⟧ ⟹ Q x *)&lt;br /&gt;
   apply assumption+            (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 10. Demostrar&lt;br /&gt;
       P a ⟶ (∃x. Q x) ⊢ ∃x. P a ⟶ Q x &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej10: &amp;quot;P a ⟶ (∃x. Q x) ⟹ ∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
  apply (case_tac &amp;quot;P a&amp;quot;) &lt;br /&gt;
                    (* ⟦P a ⟶ (∃x. Q x); P a⟧ ⟹ ∃x. P a ⟶ Q x&lt;br /&gt;
                       ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
   apply (erule impE)     &lt;br /&gt;
                    (* P a ⟹ P a&lt;br /&gt;
                       ⟦P a; ∃x. Q x⟧ ⟹ ∃x. P a ⟶ Q x&lt;br /&gt;
                       ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
    apply assumption      &lt;br /&gt;
                    (* ⟦P a; ∃x. Q x⟧ ⟹ ∃x. P a ⟶ Q x&lt;br /&gt;
                       ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
   apply (erule exE)      &lt;br /&gt;
                    (* ⋀x. ⟦P a; Q x⟧ ⟹ ∃x. P a ⟶ Q x&lt;br /&gt;
                       ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
   apply (rule_tac x=x in exI)&lt;br /&gt;
                    (* ⋀x. ⟦P a; Q x⟧ ⟹ P a ⟶ Q x&lt;br /&gt;
                       ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
   apply (rule impI)&lt;br /&gt;
                    (* ⋀x. ⟦P a; Q x; P a⟧ ⟹ Q x&lt;br /&gt;
                       ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
   apply assumption       &lt;br /&gt;
                    (* ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ ∃x. P a ⟶ Q x *)&lt;br /&gt;
  apply (rule_tac x=x in exI)&lt;br /&gt;
                    (* ⟦P a ⟶ (∃x. Q x); ¬ P a⟧ ⟹ P a ⟶ Q x*)&lt;br /&gt;
  apply (rule impI) (* ⟦P a ⟶ (∃x. Q x); ¬ P a; P a⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
                    (* ⟦P a ⟶ (∃x. Q x); P a⟧ ⟹ P a *)&lt;br /&gt;
  apply assumption  (* *)    &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 11. Demostrar&lt;br /&gt;
       (∃x. P x) ⟶ Q a ⊢ ∀x. P x ⟶ Q a&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej11: &amp;quot;(∃x. P x) ⟶ Q a ⟹ ∀x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* ⋀x. (∃x. P x) ⟶ Q a ⟹ P x ⟶ Q a *)&lt;br /&gt;
  apply (rule impI)   (* ⋀x. ⟦(∃x. P x) ⟶ Q a; P x⟧ ⟹ Q a *)&lt;br /&gt;
  apply (erule mp)    (* ⋀x. P x ⟹ ∃x. P x *) &lt;br /&gt;
   apply (erule exI)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 12. Demostrar&lt;br /&gt;
       ∀x. P x ⟶ Q a ⊢ ∃ x. P x ⟶ Q a&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej12: &amp;quot;∀x. P x ⟶ Q a ⟹ ∃x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
  apply (erule allE) (*  P ?x ⟶ Q a ⟹ ∃x. P x ⟶ Q a *)&lt;br /&gt;
  apply (erule exI)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 13. Demostrar&lt;br /&gt;
       (∀x. P x) ∨ (∀x. Q x) ⊢ ∀x. P x ∨ Q x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej13: &amp;quot;(∀x. P x) ∨ (∀x. Q x) ⟹ ∀x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  apply (rule allI)       (* ⋀x. (∀x. P x) ∨ (∀x. Q x) ⟹ P x ∨ Q x *)&lt;br /&gt;
  apply (erule disjE)     (* ⋀x. ∀x. P x ⟹ P x ∨ Q x&lt;br /&gt;
                             ⋀x. ∀x. Q x ⟹ P x ∨ Q x *)&lt;br /&gt;
   apply (erule allE)     (* ⋀x. P (?x5 x) ⟹ P x ∨ Q x&lt;br /&gt;
                             ⋀x. ∀x. Q x ⟹ P x ∨ Q x *)&lt;br /&gt;
   apply (erule disjI1)   (* ⋀x. ∀x. Q x ⟹ P x ∨ Q x *)&lt;br /&gt;
  apply (erule allE)      (* ⋀x. Q (?x8 x) ⟹ P x ∨ Q x *)&lt;br /&gt;
  apply (erule disjI2)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 14. Demostrar&lt;br /&gt;
       ∃x. P x ∧ Q x ⊢ (∃x. P x) ∧ (∃x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej14: &amp;quot;∃x. P x ∧ Q x ⟹ (∃x. P x) ∧ (∃x. Q x)&amp;quot;&lt;br /&gt;
  apply (erule exE)         (* ⋀x. P x ∧ Q x ⟹ (∃x. P x) ∧ (∃x. Q x) *)&lt;br /&gt;
  apply (rule conjI)        (* ⋀x. P x ∧ Q x ⟹ ∃x. P x&lt;br /&gt;
                               ⋀x. P x ∧ Q x ⟹ ∃x. Q x *)&lt;br /&gt;
   apply (drule conjunct1)  (* ⋀x. P x ⟹ ∃x. P x&lt;br /&gt;
                               ⋀x. P x ∧ Q x ⟹ ∃x. Q x *)&lt;br /&gt;
   apply (erule exI)        (* ⋀x. P x ∧ Q x ⟹ ∃x. Q x *)&lt;br /&gt;
  apply (drule conjunct2)   (* ⋀x. Q x ⟹ ∃x. Q x *)&lt;br /&gt;
  apply (erule exI)         (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 15. Demostrar&lt;br /&gt;
       ∀x y. P y ⟶ Q x ⊢ (∃y. P y) ⟶ (∀x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej15: &amp;quot;∀x y. P y ⟶ Q x ⟹ (∃y. P y) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule impI)       (* ⟦∀x y. P y ⟶ Q x; ∃y. P y⟧ ⟹ ∀x. Q x *)&lt;br /&gt;
  apply (rule allI)       (* ⋀x. ⟦∀x y. P y ⟶ Q x; ∃y. P y⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule exE)       (* ⋀x y. ⟦∀x y. P y ⟶ Q x; P y⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule_tac x=x in allE) &lt;br /&gt;
                          (* ⋀x y. ⟦P y; ∀y. P y ⟶ Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule_tac x=y in allE) &lt;br /&gt;
                          (* ⋀x y. ⟦P y; P y ⟶ Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule mp)        (* ⋀x y. P y ⟹ P y *)&lt;br /&gt;
   apply assumption       (* *) &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 16. Demostrar&lt;br /&gt;
       ¬(∀x. ¬(P x)) ⊢ ∃x. P x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej16: &amp;quot;¬(∀x. ¬(P x)) ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule ccontr)   (* ⟦¬ (∀x. ¬ P x); ∄x. P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)    (* ∄x. P x ⟹ ∀x. ¬ P x *)&lt;br /&gt;
  apply (rule allI)     (* ⋀x. ∄x. P x ⟹ ¬ P x *)&lt;br /&gt;
  apply (rule notI)     (* ⋀x. ⟦∄x. P x; P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)    (* ⋀x. P x ⟹ ∃x. P x *)&lt;br /&gt;
  apply (erule exI)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 17. Demostrar&lt;br /&gt;
       ∀x. ¬(P x) ⊢ ¬(∃x. P x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej17: &amp;quot;∀x. ¬(P x) ⟹ ¬(∃x. P x)&amp;quot;&lt;br /&gt;
  apply (rule notI)             (* ⟦∀x. ¬ P x; ∃x. P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)             (* ⋀x. ⟦∀x. ¬ P x; P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x. ⟦P x; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)            (* ⋀x. P x ⟹ P x *)&lt;br /&gt;
  apply assumption              (* *) &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 18. Demostrar&lt;br /&gt;
       ∃x. P x ⊢ ¬(∀x. ¬(P x))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej18: &amp;quot;∃x. P x ⟹ ¬(∀x. ¬(P x))&amp;quot;&lt;br /&gt;
  apply (rule notI)  (* ⟦∃x. P x; ∀x. ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)  (* ⋀x. ⟦∀x. ¬ P x; P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule allE) (* ⋀x. ⟦P x; ¬ P (?x4 x)⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE) (* ⋀x. P x ⟹ P (?x4 x) *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 19. Demostrar&lt;br /&gt;
       P a ⟶ (∀x. Q x) ⊢ ∀x. P a ⟶ Q x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej19: &amp;quot;P a ⟶ (∀x. Q x) ⟹ ∀x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* ⋀x. P a ⟶ (∀x. Q x) ⟹ P a ⟶ Q x *)&lt;br /&gt;
  apply (rule impI)   (* ⋀x. ⟦P a ⟶ (∀x. Q x); P a⟧ ⟹ Q x *)&lt;br /&gt;
  apply (drule mp)    (* ⋀x. P a ⟹ P a&lt;br /&gt;
                         ⋀x. ⟦P a; ∀x. Q x⟧ ⟹ Q x *)&lt;br /&gt;
   apply assumption   (* ⋀x. ⟦P a; ∀x. Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule allE)  (* ⋀x. ⟦P a; Q (?x7 x)⟧ ⟹ Q x *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 20. Demostrar&lt;br /&gt;
       {∀x y z. R x y ∧ R y z ⟶ R x z, &lt;br /&gt;
        ∀x. ¬(R x x)}&lt;br /&gt;
       ⊢ ∀x y. R x y ⟶ ¬(R y x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej20: &amp;quot;⟦∀x y z. R x y ∧ R y z ⟶ R x z;&lt;br /&gt;
              ∀x. ¬(R x x)⟧&lt;br /&gt;
             ⟹ ∀x y. R x y ⟶ ¬(R y x)&amp;quot;&lt;br /&gt;
  apply (rule allI)+            (* ⋀x y. ⟦∀x y z. R x y ∧ R y z ⟶ R x z;&lt;br /&gt;
                                          ∀x. ¬ R x x⟧&lt;br /&gt;
                                         ⟹ R x y ⟶ ¬ R y x *)&lt;br /&gt;
  apply (rule impI)             (* ⋀x y. ⟦∀x y z. R x y ∧ R y z ⟶ R x z;&lt;br /&gt;
                                          ∀x. ¬ R x x; &lt;br /&gt;
                                          R x y⟧&lt;br /&gt;
                                         ⟹ ¬ R y x *)&lt;br /&gt;
  apply (rule notI)             (* ⋀x y. ⟦∀x y z. R x y ∧ R y z ⟶ R x z;&lt;br /&gt;
                                          ∀x. ¬ R x x; &lt;br /&gt;
                                          R x y; &lt;br /&gt;
                                          R y x⟧&lt;br /&gt;
                                         ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x y. ⟦∀x. ¬ R x x; &lt;br /&gt;
                                          R x y; &lt;br /&gt;
                                          R y x;&lt;br /&gt;
                                          ∀y z. R x y ∧ R y z ⟶ R x z⟧&lt;br /&gt;
                                          ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x y. ⟦R x y; &lt;br /&gt;
                                          R y x;&lt;br /&gt;
                                          ∀y z. R x y ∧ R y z ⟶ R x z;&lt;br /&gt;
                                          ¬ R x x⟧&lt;br /&gt;
                                         ⟹ False *)&lt;br /&gt;
  apply (erule_tac x=y in allE) (* ⋀x y. ⟦R x y; &lt;br /&gt;
                                          R y x; &lt;br /&gt;
                                          ¬ R x x;&lt;br /&gt;
                                          ∀z. R x y ∧ R y z ⟶ R x z⟧&lt;br /&gt;
                                         ⟹ False *) &lt;br /&gt;
  apply (erule_tac x=x in allE) (* ⋀x y. ⟦R x y; &lt;br /&gt;
                                          R y x; &lt;br /&gt;
                                          ¬ R x x;&lt;br /&gt;
                                          R x y ∧ R y x ⟶ R x x⟧&lt;br /&gt;
                                         ⟹ False *)&lt;br /&gt;
  apply (erule notE)            (* ⋀x y. ⟦R x y; &lt;br /&gt;
                                          R y x; &lt;br /&gt;
                                          R x y ∧ R y x ⟶ R x x⟧&lt;br /&gt;
                                         ⟹ R x x *)&lt;br /&gt;
  apply (erule mp)              (* ⋀x y. ⟦R x y; &lt;br /&gt;
                                          R y x⟧ &lt;br /&gt;
                                         ⟹ R x y ∧ R y x*)&lt;br /&gt;
   apply (erule conjI)          (* ⋀x y. R y x ⟹ R y x *)&lt;br /&gt;
   apply assumption             (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* ---------------------------------------------------------------&lt;br /&gt;
  Ejercicio 21. Demostrar&lt;br /&gt;
     {∀x. P x ∨ Q x, ∃x. ¬(Q x), ∀x. R x ⟶ ¬(P x)} ⊢ ∃x. ¬(R x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej21: &amp;quot;⟦ ∀x. P x ∨ Q x; &lt;br /&gt;
              ∃x. ¬(Q x); &lt;br /&gt;
              ∀x. R x ⟶ ¬(P x) ⟧&lt;br /&gt;
             ⟹ ∃x. ¬(R x)&amp;quot;&lt;br /&gt;
  apply (erule exE)    (* ⋀x. ⟦∀x. P x ∨ Q x; ∀x. R x ⟶ ¬ P x; ¬ Q x⟧&lt;br /&gt;
                              ⟹ ∃x. ¬ R x*)&lt;br /&gt;
  apply (erule_tac x=x in allE)+&lt;br /&gt;
                       (* ⋀x. ⟦¬ Q x; P x ∨ Q x; R x ⟶ ¬ P x⟧&lt;br /&gt;
                              ⟹ ∃x. ¬ R x *)&lt;br /&gt;
  apply (erule disjE)  (* ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; P x⟧ ⟹ ∃x. ¬ R x&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x*) &lt;br /&gt;
   apply (rule_tac x=x in exI)&lt;br /&gt;
                       (* ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; P x⟧ ⟹ ¬ R x&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x *)&lt;br /&gt;
   apply (rule notI)   (* ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; P x; R x⟧ ⟹ False&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x *)&lt;br /&gt;
   apply (drule mp)    (* ⋀x. ⟦¬ Q x; P x; R x⟧ ⟹ R x&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; P x; R x; ¬ P x⟧ ⟹ False&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x *)&lt;br /&gt;
    apply assumption   (* ⋀x. ⟦¬ Q x; P x; R x; ¬ P x⟧ ⟹ False&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x *)&lt;br /&gt;
   apply (erule_tac P=&amp;quot;P x&amp;quot; in notE)  &lt;br /&gt;
                       (* ⋀x. ⟦¬ Q x; P x; R x⟧ ⟹ P x&lt;br /&gt;
                          ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x *)&lt;br /&gt;
   apply assumption    (* ⋀x. ⟦¬ Q x; R x ⟶ ¬ P x; Q x⟧ ⟹ ∃x. ¬ R x *)&lt;br /&gt;
  apply (erule notE)   (* ⋀x. ⟦R x ⟶ ¬ P x; Q x⟧ ⟹ Q x *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 22. Demostrar&lt;br /&gt;
     {∀x. P x ⟶ Q x ∨ R x, ¬(∃x. P x ∧ R x)} ⊢ ∀x. P x ⟶ Q x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej22: &amp;quot;⟦ ∀x. P x ⟶ Q x ∨ R x;  &lt;br /&gt;
              ¬(∃x. P x ∧ R x) ⟧&lt;br /&gt;
             ⟹ ∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* ⋀x. ⟦∀x. P x ⟶ Q x ∨ R x; ∄x. P x ∧ R x⟧&lt;br /&gt;
                             ⟹ P x ⟶ Q x *)&lt;br /&gt;
  apply (rule impI)   (* ⋀x. ⟦∀x. P x ⟶ Q x ∨ R x; ∄x. P x ∧ R x; P x⟧&lt;br /&gt;
                             ⟹ Q x*)&lt;br /&gt;
  apply (erule_tac x=x in allE)&lt;br /&gt;
                      (* ⋀x. ⟦∄x. P x ∧ R x; P x; P x ⟶ Q x ∨ R x⟧&lt;br /&gt;
                             ⟹ Q x *)&lt;br /&gt;
  apply (drule mp)    (* ⋀x. ⟦∄x. P x ∧ R x; P x⟧ ⟹ P x&lt;br /&gt;
                         ⋀x. ⟦∄x. P x ∧ R x; P x; Q x ∨ R x⟧ ⟹ Q x *)&lt;br /&gt;
   apply assumption   (* ⋀x. ⟦∄x. P x ∧ R x; P x; Q x ∨ R x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule disjE) (* ⋀x. ⟦∄x. P x ∧ R x; P x; Q x⟧ ⟹ Q x&lt;br /&gt;
                         ⋀x. ⟦∄x. P x ∧ R x; P x; R x⟧ ⟹ Q x *)&lt;br /&gt;
   apply assumption   (* ⋀x. ⟦∄x. P x ∧ R x; P x; R x⟧ ⟹ Q x *)&lt;br /&gt;
  apply (erule notE)  (* ⋀x. ⟦P x; R x⟧ ⟹ ∃x. P x ∧ R x *)&lt;br /&gt;
  apply (rule_tac x=x in exI)&lt;br /&gt;
                      (* ⋀x. ⟦P x; R x⟧ ⟹ P x ∧ R x *) &lt;br /&gt;
  apply (erule conjI) (* ⋀x. R x ⟹ R x *)&lt;br /&gt;
   apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 23. Demostrar&lt;br /&gt;
     ∃x y. R x y ∨ R y x ⊢ ∃x y. R x y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej23a: &amp;quot;∃x y. R x y ∨ R y x ⟹ ∃x y. R x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+   (* ⋀x y. R x y ∨ R y x ⟹ ∃x y. R x y *)&lt;br /&gt;
  apply (erule disjE)  (* ⋀x y. R x y ⟹ ∃x y. R x y&lt;br /&gt;
                          ⋀x y. R y x ⟹ ∃x y. R x y *)&lt;br /&gt;
   apply (rule_tac x=x in exI)&lt;br /&gt;
                       (* ⋀x y. R x y ⟹ ∃y. R x y&lt;br /&gt;
                          ⋀x y. R y x ⟹ ∃x y. R x y *) &lt;br /&gt;
   apply (rule_tac x=y in exI)&lt;br /&gt;
                       (* ⋀x y. R x y ⟹ R x y&lt;br /&gt;
                          ⋀x y. R y x ⟹ ∃x y. R x y *)&lt;br /&gt;
    apply assumption   (* ⋀x y. R y x ⟹ ∃x y. R x y  *)&lt;br /&gt;
  apply (rule_tac x=y in exI)&lt;br /&gt;
                       (* ⋀x y. R y x ⟹ ∃ya. R y ya *)&lt;br /&gt;
  apply (erule_tac x=x in exI)&lt;br /&gt;
                       (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej23b: &amp;quot;∃x y. R x y ∨ R y x ⟹ ∃x y. R x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+   (* ⋀x y. R x y ∨ R y x ⟹ ∃x y. R x y *)&lt;br /&gt;
  apply (erule disjE)  (* ⋀x y. R x y ⟹ ∃x y. R x y&lt;br /&gt;
                          ⋀x y. R y x ⟹ ∃x y. R x y *)&lt;br /&gt;
   apply (rule exI)+   (* ⋀x y. R x y ⟹ R (?x7 x y) (?y9 x y)&lt;br /&gt;
                          ⋀x y. R y x ⟹ ∃x y. R x y *) &lt;br /&gt;
   apply assumption    (* ⋀x y. R y x ⟹ ∃x y. R x y *)&lt;br /&gt;
  apply (rule exI)+    (* ⋀x y. R y x ⟹ R (?x11 x y) (?y13 x y) *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 24. Demostrar&lt;br /&gt;
       (∃x. ∀y. P x y) ⟶ (∀y. ∃x. P x y)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej24: &amp;quot;(∃x. ∀y. P x y) ⟶ (∀y. ∃x. P x y)&amp;quot;&lt;br /&gt;
  apply (rule impI)   (* ∃x. ∀y. P x y ⟹ ∀y. ∃x. P x y *)&lt;br /&gt;
  apply (rule allI)   (* ⋀y. ∃x. ∀y. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule exE)   (* ⋀y x. ∀y. P x y ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule allE)  (* ⋀y x. P x (?y6 y x) ⟹ ∃x. P x y *)&lt;br /&gt;
  apply (erule exI)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 25. Demostrar&lt;br /&gt;
       (∀x. P x ⟶ Q) ⟷ ((∃x. P x) ⟶ Q)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej25a: &amp;quot;(∀x. P x ⟶ Q) ⟹ ((∃x. P x) ⟶ Q)&amp;quot;&lt;br /&gt;
  apply (rule impI)   (* ∀x. P x ⟶ Q; ∃x. P x⟧ ⟹ Q *)&lt;br /&gt;
   apply (erule exE)  (* ⋀x. ⟦∀x. P x ⟶ Q; P x⟧ ⟹ Q *)&lt;br /&gt;
  apply (erule allE)  (* ⋀x. ⟦P x; P (?x7 x) ⟶ Q⟧ ⟹ Q *)&lt;br /&gt;
   apply (erule mp)   (* ⋀x. P x ⟹ P (?x7 x) *)&lt;br /&gt;
    apply assumption  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej25b: &amp;quot;((∃x. P x) ⟶ Q) ⟹ (∀x. P x ⟶ Q)&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* ⋀x. (∃x. P x) ⟶ Q ⟹ P x ⟶ Q *)&lt;br /&gt;
  apply (rule impI)   (* ⋀x. ⟦(∃x. P x) ⟶ Q; P x⟧ ⟹ Q *)&lt;br /&gt;
  apply (erule mp)    (* ⋀x. P x ⟹ ∃x. P x *)&lt;br /&gt;
  apply (erule exI)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej25: &amp;quot;(∀x. P x ⟶ Q) ⟷ ((∃x. P x) ⟶ Q)&amp;quot;&lt;br /&gt;
  apply (rule iffI)   (* ∀x. P x ⟶ Q ⟹ (∃x. P x) ⟶ Q&lt;br /&gt;
                         (∃x. P x) ⟶ Q ⟹ ∀x. P x ⟶ Q *)&lt;br /&gt;
  apply (erule ej25a) (* (∃x. P x) ⟶ Q ⟹ ∀x. P x ⟶ Q *)&lt;br /&gt;
  apply (erule ej25b) (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 26. Demostrar&lt;br /&gt;
       ((∀x. P x) ∧ (∀x. Q x)) ⟷ (∀x. P x ∧ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej26a: &amp;quot;((∀x. P x) ∧ (∀x. Q x)) ⟹ (∀x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
  apply (rule allI)         (* ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ P x ∧ Q x *)&lt;br /&gt;
  apply (rule conjI)        (* ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ P x&lt;br /&gt;
                               ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ Q x *)&lt;br /&gt;
   apply (drule conjunct1)  (* ⋀x. ∀x. P x ⟹ P x&lt;br /&gt;
                               ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ Q x *)&lt;br /&gt;
   apply (erule spec)       (* ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ Q x *)&lt;br /&gt;
   apply (drule conjunct2)  (* ⋀x. ∀x. Q x ⟹ Q x *)&lt;br /&gt;
   apply (erule spec)       (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej26b: &amp;quot;(∀x. P x ∧ Q x) ⟹ ((∀x. P x) ∧ (∀x. Q x))&amp;quot;&lt;br /&gt;
  apply (rule conjI)        (* ∀x. P x ∧ Q x ⟹ ∀x. P x&lt;br /&gt;
                               ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
  apply (rule allI)         (* ⋀x. ∀x. P x ∧ Q x ⟹ P x&lt;br /&gt;
                               ∀x. P x ∧ Q x ⟹ ∀x. Q x *)   &lt;br /&gt;
   apply (drule spec)       (* ⋀x. P (?x19 x) ∧ Q (?x19 x) ⟹ P x&lt;br /&gt;
                               ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
   apply (erule conjunct1)  (* ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
  apply (rule allI)         (* ⋀x. ∀x. P x ∧ Q x ⟹ Q x *)&lt;br /&gt;
  apply (drule spec)        (* ⋀x. P (?x24 x) ∧ Q (?x24 x) ⟹ Q x *)&lt;br /&gt;
  apply (erule conjunct2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej26: &amp;quot;((∀x. P x) ∧ (∀x. Q x)) ⟷ (∀x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)      (* (∀x. P x) ∧ (∀x. Q x) ⟹ ∀x. P x ∧ Q x&lt;br /&gt;
                            ∀x. P x ∧ Q x ⟹ (∀x. P x) ∧ (∀x. Q x) *)&lt;br /&gt;
  apply (erule ej26a)    (* ∀x. P x ∧ Q x ⟹ (∀x. P x) ∧ (∀x. Q x) *)&lt;br /&gt;
  apply (erule ej26b)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 27. Demostrar o refutar&lt;br /&gt;
       ((∀x. P x) ∨ (∀x. Q x)) ⟷ (∀x. P x ∨ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej27: &amp;quot;((∀x. P x) ∨ (∀x. Q x)) ⟷ (∀x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
(* Auto Quickcheck found a counterexample:&lt;br /&gt;
    P = {a1}&lt;br /&gt;
    Q = {a2}&lt;br /&gt;
   Evaluated terms:&lt;br /&gt;
    ∀x xa. P x ∨ Q xa = False&lt;br /&gt;
    ∀x. P x ∨ Q x = True *)    &lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 28. Demostrar o refutar&lt;br /&gt;
       ((∃x. P x) ∨ (∃x. Q x)) ⟷ (∃x. P x ∨ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej28a: &amp;quot;((∃x. P x) ∨ (∃x. Q x)) ⟹ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
  apply (erule disjE)    (* ∃x. P x ⟹ ∃x. P x ∨ Q x&lt;br /&gt;
                             ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
   apply (erule exE)     (* ⋀x. P x ⟹ ∃x. P x ∨ Q x&lt;br /&gt;
                            ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
  apply (rule exI)        (* ⋀x. P x ⟹ P (?x8 x) ∨ Q (?x8 x)&lt;br /&gt;
                             ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
    apply (erule disjI1)  (* ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
  apply (erule exE)       (* ⋀x. Q x ⟹ ∃x. P x ∨ Q x *) &lt;br /&gt;
  apply (rule exI)        (* ⋀x. Q x ⟹ P (?x13 x) ∨ Q (?x13 x) *)&lt;br /&gt;
   apply (erule disjI2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej28b: &amp;quot;(∃x. P x ∨ Q x) ⟹ ((∃x. P x) ∨ (∃x. Q x))&amp;quot;&lt;br /&gt;
  apply (erule exE)       (* ⋀x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
  apply (erule disjE)     (* ⋀x. P x ⟹ (∃x. P x) ∨ (∃x. Q x)&lt;br /&gt;
                             ⋀x. Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
   apply (rule disjI1)    (* ⋀x. P x ⟹ ∃x. P x&lt;br /&gt;
                             ⋀x. Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
   apply (erule exI)      (* ⋀x. Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
  apply (rule disjI2)     (* ⋀x. Q x ⟹ ∃x. Q x *) &lt;br /&gt;
  apply (erule exI)       (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej28: &amp;quot;((∃x. P x) ∨ (∃x. Q x)) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)       (* (∃x. P x) ∨ (∃x. Q x) ⟹ ∃x. P x ∨ Q x&lt;br /&gt;
                             ∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
   apply (erule ej28a)    (* ∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
   apply (erule ej28b)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 29. Demostrar o refutar&lt;br /&gt;
       (∀x. ∃y. P x y) ⟶ (∃y. ∀x. P x y)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej29: &amp;quot;(∀x. ∃y. P x y) ⟶ (∃y. ∀x. P x y)&amp;quot;&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
(* Auto Quickcheck found a counterexample:&lt;br /&gt;
      P = (λx. undefined)(a⇩1 := {a⇩2}, a⇩2 := {a⇩1})&lt;br /&gt;
*)    &lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 30. Demostrar o refutar&lt;br /&gt;
       (¬(∀x. P x)) ⟷ (∃x. ¬P x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej30a: &amp;quot;¬(∀x. P x) ⟹ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
  apply (rule ccontr)  (* ⟦¬ (∀x. P x); ∄x. ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)   (* ∄x. ¬ P x ⟹ ∀x. P x *)&lt;br /&gt;
  apply (rule allI)    (* ⋀x. ∄x. ¬ P x ⟹ P x *)&lt;br /&gt;
  apply (rule ccontr)  (* ⋀x. ⟦∄x. ¬ P x; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)   (* ⋀x. ¬ P x ⟹ ∃x. ¬ P x *)&lt;br /&gt;
  apply (erule exI)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej30b: &amp;quot;(∃x. ¬P x) ⟹ ¬(∀x. P x)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* ⟦¬ (∀x. P x); ∄x. ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)     (* ⋀x. ⟦∀x. P x; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (drule spec)    (* ⋀x. ⟦¬ P x; P (?x4 x)⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)    (* ⋀x. P (?x4 x) ⟹ P x *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej30: &amp;quot;(¬(∀x. P x)) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)     (* ¬ (∀x. P x) ⟹ ∃x. ¬ P x&lt;br /&gt;
                           ∃x. ¬ P x ⟹ ¬ (∀x. P x) *)&lt;br /&gt;
   apply (erule ej30a)  (* ∃x. ¬ P x ⟹ ¬ (∀x. P x) *)&lt;br /&gt;
   apply (erule ej30b)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 31. Demostrar o refutar&lt;br /&gt;
     {∀x. P a x x, &lt;br /&gt;
      ∀x y z. P x y z ⟶ P (f x) y (f z)} &lt;br /&gt;
     ⊢ P (f a) a (f a)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej31: &amp;quot;⟦ ∀x. P a x x;&lt;br /&gt;
              ∀x y z. P x y z ⟶ P (f x) y (f z) ⟧&lt;br /&gt;
             ⟹ P (f a) a (f a)&amp;quot;&lt;br /&gt;
  apply (erule allE)+   (* ⟦P a ?x ?x;&lt;br /&gt;
                            P ?x2 ?y4 ?z6 ⟶ P (f ?x2) ?y4 (f ?z6)⟧&lt;br /&gt;
                           ⟹ P (f a) a (f a) *)&lt;br /&gt;
  apply (erule mp)      (* P a ?x ?x ⟹ P a a a *)&lt;br /&gt;
   apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 32. Demostrar o refutar&lt;br /&gt;
     {∀x. P a x x, &lt;br /&gt;
      ∀x y z. P x y z ⟶ P (f x) y (f z)⟧&lt;br /&gt;
     ⊢ ∃z. P (f a) z (f (f a))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej32: &amp;quot;⟦ ∀x. P a x x;&lt;br /&gt;
               ∀x y z. P x y z ⟶ P (f x) y (f z) ⟧&lt;br /&gt;
             ⟹ ∃z. P (f a) z (f (f a))&amp;quot;&lt;br /&gt;
  apply (erule allE)+  (* ⟦P a ?x ?x;&lt;br /&gt;
                           P ?x2 ?y4 ?z6 ⟶ P (f ?x2) ?y4 (f ?z6)⟧&lt;br /&gt;
                          ⟹ ∃z. P (f a) z (f (f a)) *)&lt;br /&gt;
  apply (drule mp)     (* P a ?x ?x ⟹ P ?x2 ?y4 ?z6&lt;br /&gt;
                          ⟦P a ?x ?x; P (f ?x2) ?y4 (f ?z6)⟧&lt;br /&gt;
                          ⟹ ∃z. P (f a) z (f (f a)) *)&lt;br /&gt;
   apply assumption    (* ⟦P a ?x ?x; P (f a) ?x (f ?x)⟧&lt;br /&gt;
                          ⟹ ∃z. P (f a) z (f (f a)) *)&lt;br /&gt;
  apply (erule exI)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 33. Demostrar o refutar&lt;br /&gt;
     {∀y. Q a y, &lt;br /&gt;
      ∀x y. Q x y ⟶ Q (s x) (s y)} &lt;br /&gt;
     ⊢ ∃z. Qa z ∧ Q z (s (s a))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej33: &amp;quot;⟦ ∀y. Q a y;&lt;br /&gt;
               ∀x y. Q x y ⟶ Q (s x) (s y) ⟧&lt;br /&gt;
             ⟹ ∃z. Q a z ∧ Q z (s (s a))&amp;quot;&lt;br /&gt;
  apply (erule allE)+   (* ⟦Q a ?y; &lt;br /&gt;
                            Q ?x2 ?y4 ⟶ Q (s ?x2) (s ?y4)⟧&lt;br /&gt;
                           ⟹ ∃z. Q a z ∧ Q z (s (s a)) *)&lt;br /&gt;
  apply (drule mp)      (* Q a ?y ⟹ Q ?x2 ?y4&lt;br /&gt;
                           ⟦Q a ?y; Q (s ?x2) (s ?y4)⟧&lt;br /&gt;
                           ⟹ ∃z. Q a z ∧ Q z (s (s a)) *)&lt;br /&gt;
   apply assumption     (* ⟦Q a ?y; Q (s ?x2) (s ?y4)⟧&lt;br /&gt;
                           ⟹ ∃z. Q a z ∧ Q z (s (s a))*)&lt;br /&gt;
  apply (rule exI)      (* ⟦Q a ?y; Q (s a) (s ?y)⟧&lt;br /&gt;
                           ⟹ Q a ?z9 ∧ Q ?z9 (s (s a)) *) &lt;br /&gt;
  apply (rule conjI)    (* ⟦Q a ?y; Q (s a) (s ?y)⟧ ⟹ Q a ?z9&lt;br /&gt;
                           ⟦Q a ?y; Q (s a) (s ?y)⟧ ⟹ Q ?z9 (s (s a)) *) &lt;br /&gt;
   apply assumption+    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 34. Demostrar o refutar&lt;br /&gt;
     {∀x. P a x x, &lt;br /&gt;
      ∀x y z. P x y z ⟶ P (f x) y (f z)⟧&lt;br /&gt;
     ⊢ ∃z. P (f a) z (f (f a))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_34a:&lt;br /&gt;
  &amp;quot;⟦∀x. P a x x; ∀x y z. P x y z ⟶ P (f x) y (f z)⟧&lt;br /&gt;
   ⟹ ∃z. P (f a) z (f (f a))&amp;quot;&lt;br /&gt;
  apply (erule allE)+  (* ⟦P a ?x ?x;&lt;br /&gt;
                           P ?x2 ?y4 ?z6 ⟶ P (f ?x2) ?y4 (f ?z6)⟧&lt;br /&gt;
                          ⟹ ∃z. P (f a) z (f (f a)) *)&lt;br /&gt;
  apply (drule mp)     (* P a ?x ?x ⟹ P ?x2 ?y4 ?z6&lt;br /&gt;
                          ⟦P a ?x ?x; P (f ?x2) ?y4 (f ?z6)⟧&lt;br /&gt;
                          ⟹ ∃z. P (f a) z (f (f a)) *)&lt;br /&gt;
   apply assumption    (* ⟦P a ?x ?x; P (f ?x2) ?y4 (f ?z6)⟧&lt;br /&gt;
                          ⟹ ∃z. P (f a) z (f (f a)) *)&lt;br /&gt;
  apply (erule exI)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 35. Demostrar o refutar&lt;br /&gt;
     {∀y. Q a y, &lt;br /&gt;
      ∀x y. Q x y ⟶ Q (s x) (s y)} &lt;br /&gt;
     ⊢ ∃z. Qa z ∧ Q z (s (s a))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_35a:&lt;br /&gt;
  &amp;quot;⟦∀y. Q a y; &lt;br /&gt;
    ∀x y. Q x y ⟶ Q (s x) (s y)⟧ &lt;br /&gt;
   ⟹ ∃z. Q a z ∧ Q z (s (s a))&amp;quot;&lt;br /&gt;
  apply (erule allE)+  (* ⟦Q a ?y; Q ?x2 ?y4 ⟶ Q (s ?x2) (s ?y4)⟧&lt;br /&gt;
                          ⟹ ∃z. Q a z ∧ Q z (s (s a)) *)&lt;br /&gt;
  apply (drule mp)     (* Q a ?y ⟹ Q ?x2 ?y4&lt;br /&gt;
                          ⟦Q a ?y; Q (s ?x2) (s ?y4)⟧&lt;br /&gt;
                          ⟹ ∃z. Q a z ∧ Q z (s (s a)) *)&lt;br /&gt;
   apply assumption    (* ⟦Q a ?y; Q (s ?x2) (s ?y4)⟧&lt;br /&gt;
                          ⟹ ∃z. Q a z ∧ Q z (s (s a)) *)&lt;br /&gt;
  apply (rule exI)     (* ⟦Q a ?y; Q (s a) (s ?y)⟧&lt;br /&gt;
                          ⟹ Q a ?z9 ∧ Q ?z9 (s (s a)) *)&lt;br /&gt;
  apply (rule conjI)   (* ⟦Q a ?y; Q (s a) (s ?y)⟧ ⟹ Q a ?z9&lt;br /&gt;
                          ⟦Q a ?y; Q (s a) (s ?y)⟧ ⟹ Q ?z9 (s (s a)) *)&lt;br /&gt;
   apply assumption+   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 36. Demostrar o refutar&lt;br /&gt;
     {x = f x, odd (f x)} ⊢ odd x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_36a:&lt;br /&gt;
  &amp;quot;⟦x = f x; odd (f x)⟧ ⟹ odd x&amp;quot;&lt;br /&gt;
  apply(drule sym)     (* ⟦odd (f x); f x = x⟧ ⟹ odd x *)&lt;br /&gt;
  apply (drule subst)  (* odd (f x) ⟹ ?P2 (f x)&lt;br /&gt;
                          ⟦odd (f x); ?P2 x⟧ ⟹ odd x *)&lt;br /&gt;
   apply assumption    (* ⟦odd (f x); odd x⟧ ⟹ odd x*)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_36b:&lt;br /&gt;
  &amp;quot;⟦x = f x; odd (f x)⟧ ⟹ odd x&amp;quot;&lt;br /&gt;
  apply (erule ssubst) (* odd (f x) ⟹ odd (f x) *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_36c:&lt;br /&gt;
  &amp;quot;⟦x = f x; odd (f x)⟧ ⟹ odd x&amp;quot;&lt;br /&gt;
by (rule ssubst)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 37. Demostrar o refutar&lt;br /&gt;
     {x = f x, triple (f x) (f x) x} ⊢ triple x x x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_37a:&lt;br /&gt;
  &amp;quot;⟦x = f x; triple (f x) (f x) x⟧ ⟹ triple x x x&amp;quot;&lt;br /&gt;
  apply (drule sym)   (* ⟦triple (f x) (f x) x; f x = x⟧&lt;br /&gt;
                         ⟹ triple x x x *)&lt;br /&gt;
  apply (drule subst) (* triple (f x) (f x) x ⟹ ?P2 (f x)&lt;br /&gt;
                         ⟦triple (f x) (f x) x; ?P2 x⟧ ⟹ triple x x x *)&lt;br /&gt;
   apply assumption   (* ⟦triple (f x) (f x) x; triple x x x⟧&lt;br /&gt;
                         ⟹ triple x x x *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done                &lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_37b:&lt;br /&gt;
  &amp;quot;⟦x = f x; triple (f x) (f x) x⟧ ⟹ triple x x x&amp;quot;&lt;br /&gt;
  apply (drule_tac s=&amp;quot;f x&amp;quot; in ssubst)&lt;br /&gt;
                      (* triple (f x) (f x) x ⟹ ?P (f x)&lt;br /&gt;
                         ⟦triple (f x) (f x) x; ?P x⟧ ⟹ triple x x x *)&lt;br /&gt;
   apply assumption   (* ⟦triple (f x) (f x) x; triple x x x⟧&lt;br /&gt;
                         ⟹ triple x x x *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done                &lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_37c:&lt;br /&gt;
  &amp;quot;⟦x = f x; triple (f x) (f x) x⟧ ⟹ triple x x x&amp;quot;&lt;br /&gt;
  by (rule ssubst)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Ejercicios&amp;diff=579</id>
		<title>Ejercicios</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Ejercicios&amp;diff=579"/>
		<updated>2019-04-21T09:25:21Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;En esta página se encuentran los ejercicios para resolver de manera colaborativa que complementan al [https://www.cs.us.es/~jalonso/cursos/lmf-18/ejercicios/ejercicios-LMF-2018-19.pdf libro de ejercicios].&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 1&amp;#039;&amp;#039;&amp;#039;: Sintaxis y semántica de la lógica proposicional. ([[R1 |Enunciado]] y [[Relación 1 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 2&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional. ([[R2 |Enunciado]] y [[Relación 2 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 3&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional (II). ([[R3 |Enunciado]] y [[Relación 3 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 4&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica proposicional con Isabelle ([[R4 |Enunciado]], [[Relación 4 |Solución colaborativa]] y [[Sol 4 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 5&amp;#039;&amp;#039;&amp;#039;: Sintaxis y semántica de la lógica de primer orden. ([[R5 |Enunciado]] y [[Relación 5 |Solución colaborativa]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 6&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R6.thy Deducción natural en lógica de primer orden con Isabelle] ([[R6 |Enunciado]], [[Relación  |Solución colaborativa]] y [[Sol 6 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 7&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R7.thy Deducción natural en lógica proposicional con Isabelle basada en tácticas] ([[R7 |Enunciado]], [[Relación 7 |Solución colaborativa]] y [[Sol 7 | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 7b&amp;#039;&amp;#039;&amp;#039;: Deducción natural en lógica de primer orden con Isabelle basada en tácticas. ([[Sol 7b | una solución]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Relación 8&amp;#039;&amp;#039;&amp;#039;: [https://www.cs.us.es/~mjoseh/cursos/lmf-18/relaciones_ejercicios/R8.thy Argumentación en lógica de primer orden con Isabelle.] ([[R8 |Enunciado]], [[Relación 8 |Solución colaborativa]] y [[Sol 8 | una solución]]).&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_6&amp;diff=578</id>
		<title>Sol 6</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_6&amp;diff=578"/>
		<updated>2019-04-21T09:22:14Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
chapter {* R6: Deducción natural en lógica de primer orden *}&lt;br /&gt;
&lt;br /&gt;
theory R6&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Demostrar o refutar los siguientes lemas usando sólo las reglas&lt;br /&gt;
  básicas de deducción natural de la lógica proposicional, de los&lt;br /&gt;
  cuantificadores y de la igualdad: &lt;br /&gt;
  · conjI:      ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:  P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:  P ∧ Q ⟹ Q  &lt;br /&gt;
  · notnotD:    ¬¬ P ⟹ P&lt;br /&gt;
  · mp:         ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · impI:       (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · disjI1:     P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:     Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:      ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:     False ⟹ P&lt;br /&gt;
  · notE:       ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:       (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · iffI:       ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:      ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:      ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · ccontr:     (¬P ⟹ False) ⟹ P&lt;br /&gt;
&lt;br /&gt;
  · allI:       ⟦∀x. P x; P x ⟹ R⟧ ⟹ R&lt;br /&gt;
  · allE:       (⋀x. P x) ⟹ ∀x. P x&lt;br /&gt;
  · exI:        P x ⟹ ∃x. P x&lt;br /&gt;
  · exE:        ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q&lt;br /&gt;
&lt;br /&gt;
  · refl:       t = t&lt;br /&gt;
  · subst:      ⟦s = t; P s⟧ ⟹ P t&lt;br /&gt;
  · trans:      ⟦r = s; s = t⟧ ⟹ r = t&lt;br /&gt;
  · sym:        s = t ⟹ t = s&lt;br /&gt;
  · not_sym:    t ≠ s ⟹ s ≠ t&lt;br /&gt;
  · ssubst:     ⟦t = s; P s⟧ ⟹ P t&lt;br /&gt;
  · box_equals: ⟦a = b; a = c; b = d⟧ ⟹ a: = d&lt;br /&gt;
  · arg_cong:   x = y ⟹ f x = f y&lt;br /&gt;
  · fun_cong:   f = g ⟹ f x = g x&lt;br /&gt;
  · cong:       ⟦f = g; x = y⟧ ⟹ f x = g y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se usarán las reglas notnotI y mt que demostramos a continuación.&lt;br /&gt;
  *}&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. Demostrar&lt;br /&gt;
       ∀x. P x ⟶ Q x ⊢ (∀x. P x) ⟶ (∀x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_1a: &lt;br /&gt;
  &amp;quot;∀x. P x ⟶ Q x ⟹ (∀x. P x) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_1b: &lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. P x) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P a&amp;quot; using `∀x. P x` ..&lt;br /&gt;
    have &amp;quot;P a ⟶ Q a&amp;quot; using assms(1) ..&lt;br /&gt;
    thus &amp;quot;Q a&amp;quot; using `P a` ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_1c: &lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. P x) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P a&amp;quot; using `∀x. P x` by (rule allE)&lt;br /&gt;
    have &amp;quot;P a ⟶ Q a&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
    thus &amp;quot;Q a&amp;quot; using `P a` by (rule mp)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. Demostrar&lt;br /&gt;
       ∃x. ¬(P x) ⊢ ¬(∀x. P x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_2a: &amp;quot;∃x. ¬(P x) ⟹ ¬(∀x. P x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_2b: &lt;br /&gt;
  assumes &amp;quot;∃x. ¬(P x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. P x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  obtain a where &amp;quot;¬(P a)&amp;quot; using assms(1) .. &lt;br /&gt;
  have &amp;quot;P a&amp;quot; using `∀x. P x` ..&lt;br /&gt;
  with `¬(P a)` show False ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_2c: &lt;br /&gt;
  assumes &amp;quot;∃x. ¬(P x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. P x)&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  obtain a where &amp;quot;¬(P a)&amp;quot; using assms(1) by (rule exE)&lt;br /&gt;
  have &amp;quot;P a&amp;quot; using `∀x. P x` by (rule allE)&lt;br /&gt;
  with `¬(P a)` show False by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3. Demostrar&lt;br /&gt;
       ∀x. P x ⊢ ∀y. P y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_3a: &amp;quot;∀x. P x  ⟹ ∀y. P y&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_3b: &lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀y. P y&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;P a&amp;quot; using assms ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_3c: &lt;br /&gt;
  assumes &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀y. P y&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;P a&amp;quot; using assms by (rule allE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. Demostrar&lt;br /&gt;
       ∀x. P x ⟶ Q x ⊢ (∀x. ¬(Q x)) ⟶ (∀x. ¬ (P x))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_4a: &lt;br /&gt;
  &amp;quot;∀x. P x ⟶ Q x ⟹ (∀x. ¬(Q x)) ⟶ (∀x. ¬ (P x))&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_4b: &lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. ¬(Q x)) ⟶ (∀x. ¬ (P x))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∀x. ¬(Q x)&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    show &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      have &amp;quot;P a ⟶ Q a&amp;quot; using assms ..&lt;br /&gt;
      hence &amp;quot;Q a&amp;quot; using `P a` ..&lt;br /&gt;
      have &amp;quot;¬(Q a)&amp;quot; using `∀x. ¬(Q x)` ..&lt;br /&gt;
      thus False using `Q a` ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_4c: &lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∀x. ¬(Q x)) ⟶ (∀x. ¬ (P x))&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume &amp;quot;∀x. ¬(Q x)&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    show &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      have &amp;quot;P a ⟶ Q a&amp;quot; using assms by (rule allE)&lt;br /&gt;
      hence &amp;quot;Q a&amp;quot; using `P a` by (rule mp)&lt;br /&gt;
      have &amp;quot;¬(Q a)&amp;quot; using `∀x. ¬(Q x)` by (rule allE) &lt;br /&gt;
      thus False using `Q a` by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 5. Demostrar&lt;br /&gt;
       ∀x. P x  ⟶ ¬(Q x) ⊢ ¬(∃x. P x ∧ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_5a: &lt;br /&gt;
  &amp;quot;∀x. P x  ⟶ ¬(Q x) ⟹ ¬(∃x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_5b: &lt;br /&gt;
  assumes &amp;quot;∀x. P x  ⟶ ¬(Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∃x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∃x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P a ∧ Q a&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;P a&amp;quot; ..&lt;br /&gt;
  have &amp;quot;P a ⟶ ¬(Q a)&amp;quot; using assms ..&lt;br /&gt;
  hence &amp;quot;¬(Q a)&amp;quot; using `P a` ..&lt;br /&gt;
  have &amp;quot;Q a&amp;quot; using `P a ∧ Q a` ..&lt;br /&gt;
  with `¬(Q a)` show False ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_5c: &lt;br /&gt;
  assumes &amp;quot;∀x. P x  ⟶ ¬(Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∃x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume &amp;quot;∃x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P a ∧ Q a&amp;quot; by (rule exE)&lt;br /&gt;
  hence &amp;quot;P a&amp;quot; by (rule conjunct1)&lt;br /&gt;
  have &amp;quot;P a ⟶ ¬(Q a)&amp;quot; using assms by (rule allE)&lt;br /&gt;
  hence &amp;quot;¬(Q a)&amp;quot; using `P a` by (rule mp)&lt;br /&gt;
  have &amp;quot;Q a&amp;quot; using `P a ∧ Q a` by (rule conjunct2)&lt;br /&gt;
  with `¬(Q a)` show False by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 6. Demostrar&lt;br /&gt;
       ∀x y. P x y ⊢ ∀u v. P u v&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_6a: &lt;br /&gt;
  &amp;quot;∀x y. P x y ⟹ ∀u v. P u v&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_6b: &lt;br /&gt;
  assumes &amp;quot;∀x y. P x y&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀u v. P u v&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  fix a &lt;br /&gt;
  show &amp;quot;∀v. P a v&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix b&lt;br /&gt;
    have &amp;quot;∀y. P a y&amp;quot; using assms .. &lt;br /&gt;
    thus &amp;quot;P a b&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada simplificada es›&lt;br /&gt;
lemma ejercicio_6b2: &lt;br /&gt;
  assumes &amp;quot;∀x y. P x y&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀u v. P u v&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  have &amp;quot;∀y. P a y&amp;quot; using assms .. &lt;br /&gt;
  thus &amp;quot;P a b&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_6c: &lt;br /&gt;
  assumes &amp;quot;∀x y. P x y&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀u v. P u v&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  have &amp;quot;∀y. P a y&amp;quot; using assms by (rule allE) &lt;br /&gt;
  thus &amp;quot;P a b&amp;quot; by (rule allE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 7. Demostrar&lt;br /&gt;
       ∃x y. P x y ⟹ ∃u v. P u v&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_7a: &lt;br /&gt;
  &amp;quot;∃x y. P x y ⟹ ∃u v. P u v&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_7b: &lt;br /&gt;
  assumes &amp;quot;∃x y. P x y&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃u v. P u v&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. P a y&amp;quot; using assms ..&lt;br /&gt;
  then obtain b where &amp;quot;P a b&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;∃v. P a v&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃u v. P u v&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 8. Demostrar&lt;br /&gt;
       ∃x. ∀y. P x y ⊢ ∀y. ∃x. P x y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_8a: &lt;br /&gt;
  &amp;quot;∃x. ∀y. P x y ⟹ ∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_8b: &lt;br /&gt;
  assumes &amp;quot;∃x. ∀y. P x y&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix b&lt;br /&gt;
  obtain a where &amp;quot;∀y. P a y&amp;quot; using assms ..&lt;br /&gt;
  hence &amp;quot;P a b&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃x. P x b&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_8c: &lt;br /&gt;
  assumes &amp;quot;∃x. ∀y. P x y&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix b&lt;br /&gt;
  obtain a where &amp;quot;∀y. P a y&amp;quot; using assms by (rule exE)&lt;br /&gt;
  hence &amp;quot;P a b&amp;quot; by (rule allE)&lt;br /&gt;
  thus &amp;quot;∃x. P x b&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 9. Demostrar&lt;br /&gt;
       ∃x. P a ⟶ Q x ⊢ P a ⟶ (∃x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_9a: &lt;br /&gt;
  &amp;quot;∃x. P a ⟶ Q x ⟹ P a ⟶ (∃x. Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_9b: &lt;br /&gt;
  assumes &amp;quot;∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;P a ⟶ (∃x. Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;P a&amp;quot;&lt;br /&gt;
  obtain b where &amp;quot;P a ⟶ Q b&amp;quot; using assms ..&lt;br /&gt;
  hence &amp;quot;Q b&amp;quot; using `P a` ..&lt;br /&gt;
  thus &amp;quot;∃x. Q x&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_9c: &lt;br /&gt;
  assumes &amp;quot;∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;P a ⟶ (∃x. Q x)&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume &amp;quot;P a&amp;quot;&lt;br /&gt;
  obtain b where &amp;quot;P a ⟶ Q b&amp;quot; using assms by (rule exE)&lt;br /&gt;
  hence &amp;quot;Q b&amp;quot; using `P a` by (rule mp)&lt;br /&gt;
  thus &amp;quot;∃x. Q x&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 10. Demostrar&lt;br /&gt;
       P a ⟶ (∃x. Q x) ⊢ ∃x. P a ⟶ Q x &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_10a: &lt;br /&gt;
  &amp;quot;P a ⟶ (∃x. Q x) ⟹ ∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_10b: &lt;br /&gt;
  fixes P Q :: &amp;quot;&amp;#039;b ⇒ bool&amp;quot; &lt;br /&gt;
  assumes &amp;quot;P a ⟶ (∃x. Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬(P a) ∨ P a&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
  proof &lt;br /&gt;
    assume &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    have &amp;quot;P a ⟶ Q a&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      with `¬(P a)` show &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
    qed&lt;br /&gt;
    thus &amp;quot;∃x. P a ⟶ Q x&amp;quot; ..&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    with assms have &amp;quot;∃x. Q x&amp;quot; by (rule mp)&lt;br /&gt;
    then obtain b where &amp;quot;Q b&amp;quot; .. &lt;br /&gt;
    have &amp;quot;P a ⟶ Q b&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      note `Q b` &lt;br /&gt;
      thus &amp;quot;Q b&amp;quot; .&lt;br /&gt;
    qed&lt;br /&gt;
    thus &amp;quot;∃x. P a ⟶ Q x&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_10c: &lt;br /&gt;
  fixes P Q :: &amp;quot;&amp;#039;b ⇒ bool&amp;quot; &lt;br /&gt;
  assumes &amp;quot;P a ⟶ (∃x. Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;¬(P a) ∨ P a&amp;quot; by (rule excluded_middle)&lt;br /&gt;
  thus &amp;quot;∃x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    have &amp;quot;P a ⟶ Q a&amp;quot;&lt;br /&gt;
    proof (rule impI)&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      with `¬(P a)` show &amp;quot;Q a&amp;quot; by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
    thus &amp;quot;∃x. P a ⟶ Q x&amp;quot; by (rule exI)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    with assms have &amp;quot;∃x. Q x&amp;quot; by (rule mp)&lt;br /&gt;
    then obtain b where &amp;quot;Q b&amp;quot; by (rule exE)&lt;br /&gt;
    have &amp;quot;P a ⟶ Q b&amp;quot;&lt;br /&gt;
    proof (rule impI)&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      note `Q b` &lt;br /&gt;
      thus &amp;quot;Q b&amp;quot; by this&lt;br /&gt;
    qed&lt;br /&gt;
    thus &amp;quot;∃x. P a ⟶ Q x&amp;quot; by (rule exI)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 11. Demostrar&lt;br /&gt;
       (∃x. P x) ⟶ Q a ⊢ ∀x. P x ⟶ Q a&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_11a: &lt;br /&gt;
  &amp;quot;(∃x. P x) ⟶ Q a ⟹ ∀x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_11b: &lt;br /&gt;
  assumes &amp;quot;(∃x. P x) ⟶ Q a&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix b&lt;br /&gt;
  show &amp;quot;P b ⟶ Q a&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;P b&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃x. P x&amp;quot; ..&lt;br /&gt;
    with assms show &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_11c: &lt;br /&gt;
  assumes &amp;quot;(∃x. P x) ⟶ Q a&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix b&lt;br /&gt;
  show &amp;quot;P b ⟶ Q a&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;P b&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃x. P x&amp;quot; by (rule exI)&lt;br /&gt;
    with assms show &amp;quot;Q a&amp;quot; by (rule mp)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 12. Demostrar&lt;br /&gt;
       ∀x. P x ⟶ Q a ⊢ ∃ x. P x ⟶ Q a&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_12a: &lt;br /&gt;
  &amp;quot;∀x. P x ⟶ Q a ⟹ ∃x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_12b: &lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P b ⟶ Q a&amp;quot; using assms ..&lt;br /&gt;
  thus &amp;quot;∃x. P x ⟶ Q a&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_12c: &lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P x ⟶ Q a&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P b ⟶ Q a&amp;quot; using assms by (rule allE)&lt;br /&gt;
  thus &amp;quot;∃x. P x ⟶ Q a&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 13. Demostrar&lt;br /&gt;
       (∀x. P x) ∨ (∀x. Q x) ⊢ ∀x. P x ∨ Q x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_13a: &lt;br /&gt;
  &amp;quot;(∀x. P x) ∨ (∀x. Q x) ⟹ ∀x. P x ∨ Q x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_13b: &lt;br /&gt;
  assumes &amp;quot;(∀x. P x) ∨ (∀x. Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P x ∨ Q x&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  note assms&lt;br /&gt;
  thus &amp;quot;P a ∨ Q a&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
    hence &amp;quot;P a&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;P a ∨ Q a&amp;quot; ..&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
    hence &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;P a ∨ Q a&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_13c: &lt;br /&gt;
  assumes &amp;quot;(∀x. P x) ∨ (∀x. Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P x ∨ Q x&amp;quot;&lt;br /&gt;
proof (rule  allI)&lt;br /&gt;
  fix a&lt;br /&gt;
  note assms&lt;br /&gt;
  thus &amp;quot;P a ∨ Q a&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
    hence &amp;quot;P a&amp;quot; by (rule allE)&lt;br /&gt;
    thus &amp;quot;P a ∨ Q a&amp;quot; by (rule disjI1)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
    hence &amp;quot;Q a&amp;quot; by (rule allE)&lt;br /&gt;
    thus &amp;quot;P a ∨ Q a&amp;quot; by (rule disjI2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 14. Demostrar&lt;br /&gt;
       ∃x. P x ∧ Q x ⊢ (∃x. P x) ∧ (∃x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_14a: &lt;br /&gt;
  &amp;quot;∃x. P x ∧ Q x ⟹ (∃x. P x) ∧ (∃x. Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_14b: &lt;br /&gt;
  assumes &amp;quot;∃x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃x. P x) ∧ (∃x. Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  obtain a where &amp;quot;P a ∧ Q a&amp;quot; using assms ..&lt;br /&gt;
  hence &amp;quot;P a&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃x. P x&amp;quot; ..&lt;br /&gt;
next&lt;br /&gt;
  obtain a where &amp;quot;P a ∧ Q a&amp;quot; using assms ..&lt;br /&gt;
  hence &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃x. Q x&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_14c: &lt;br /&gt;
  assumes &amp;quot;∃x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃x. P x) ∧ (∃x. Q x)&amp;quot;&lt;br /&gt;
proof (rule conjI)&lt;br /&gt;
  obtain a where &amp;quot;P a ∧ Q a&amp;quot; using assms by (rule exE)&lt;br /&gt;
  hence &amp;quot;P a&amp;quot; by (rule conjunct1)&lt;br /&gt;
  thus &amp;quot;∃x. P x&amp;quot; by (rule exI)&lt;br /&gt;
next&lt;br /&gt;
  obtain a where &amp;quot;P a ∧ Q a&amp;quot; using assms by (rule exE)&lt;br /&gt;
  hence &amp;quot;Q a&amp;quot; by (rule conjunct2)&lt;br /&gt;
  thus &amp;quot;∃x. Q x&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 15. Demostrar&lt;br /&gt;
       ∀x y. P y ⟶ Q x ⊢ (∃y. P y) ⟶ (∀x. Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_15a: &lt;br /&gt;
  &amp;quot;∀x y. P y ⟶ Q x ⟹ (∃y. P y) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_15b: &lt;br /&gt;
  assumes &amp;quot;∀x y. P y ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃y. P y) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∃y. P y&amp;quot;&lt;br /&gt;
  then obtain b where &amp;quot;P b&amp;quot; ..&lt;br /&gt;
  show &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;∀y. P y ⟶ Q a&amp;quot; using assms ..&lt;br /&gt;
    hence &amp;quot;P b ⟶ Q a&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;Q a&amp;quot; using `P b` ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_15c: &lt;br /&gt;
  assumes &amp;quot;∀x y. P y ⟶ Q x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;(∃y. P y) ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume &amp;quot;∃y. P y&amp;quot;&lt;br /&gt;
  then obtain b where &amp;quot;P b&amp;quot; by (rule exE)&lt;br /&gt;
  show &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;∀y. P y ⟶ Q a&amp;quot; using assms by (rule allE)&lt;br /&gt;
    hence &amp;quot;P b ⟶ Q a&amp;quot; by (rule allE)&lt;br /&gt;
    thus &amp;quot;Q a&amp;quot; using `P b` by (rule mp)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 16. Demostrar&lt;br /&gt;
       ¬(∀x. ¬(P x)) ⊢ ∃x. P x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_16a: &lt;br /&gt;
  &amp;quot;¬(∀x. ¬(P x)) ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_16b: &lt;br /&gt;
  assumes &amp;quot;¬(∀x. ¬(P x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume &amp;quot;¬(∃x. P x)&amp;quot;&lt;br /&gt;
  have &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    show &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      hence &amp;quot;∃x. P x&amp;quot; ..&lt;br /&gt;
      with `¬(∃x. P x)` show False ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
  with assms show False ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_16c: &lt;br /&gt;
  assumes &amp;quot;¬(∀x. ¬(P x))&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
proof (rule ccontr)&lt;br /&gt;
  assume &amp;quot;¬(∃x. P x)&amp;quot;&lt;br /&gt;
  have &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    show &amp;quot;¬(P a)&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P a&amp;quot;&lt;br /&gt;
      hence &amp;quot;∃x. P x&amp;quot; by (rule exI)&lt;br /&gt;
      with `¬(∃x. P x)` show False by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
  with assms show False by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 17. Demostrar&lt;br /&gt;
       ∀x. ¬(P x) ⊢ ¬(∃x. P x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_17a: &lt;br /&gt;
  &amp;quot;∀x. ¬(P x) ⟹ ¬(∃x. P x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_17b: &lt;br /&gt;
  assumes &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∃x. P x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P a&amp;quot; ..&lt;br /&gt;
  have &amp;quot;¬(P a)&amp;quot; using assms ..&lt;br /&gt;
  thus False using `P a` ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_17c: &lt;br /&gt;
  assumes &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∃x. P x)&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P a&amp;quot; by (rule exE)&lt;br /&gt;
  have &amp;quot;¬(P a)&amp;quot; using assms by (rule allE)&lt;br /&gt;
  thus False using `P a` by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 18. Demostrar&lt;br /&gt;
       ∃x. P x ⊢ ¬(∀x. ¬(P x))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_18a: &lt;br /&gt;
  &amp;quot;∃x. P x ⟹ ¬(∀x. ¬(P x))&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_18b: &lt;br /&gt;
  assumes &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. ¬(P x))&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  obtain a where &amp;quot;P a&amp;quot; using assms ..&lt;br /&gt;
  have &amp;quot;¬(P a)&amp;quot; using `∀x. ¬(P x)` ..&lt;br /&gt;
  thus False using `P a` ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_18c: &lt;br /&gt;
  assumes &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;¬(∀x. ¬(P x))&amp;quot;&lt;br /&gt;
proof (rule notI)&lt;br /&gt;
  assume &amp;quot;∀x. ¬(P x)&amp;quot;&lt;br /&gt;
  obtain a where &amp;quot;P a&amp;quot; using assms by (rule exE)&lt;br /&gt;
  have &amp;quot;¬(P a)&amp;quot; using `∀x. ¬(P x)` by (rule allE)&lt;br /&gt;
  thus False using `P a` by (rule notE)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 19. Demostrar&lt;br /&gt;
       P a ⟶ (∀x. Q x) ⊢ ∀x. P a ⟶ Q x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_19a:&lt;br /&gt;
  &amp;quot;P a ⟶ (∀x. Q x) ⟹ ∀x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_19b: &lt;br /&gt;
  assumes &amp;quot;P a ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix b&lt;br /&gt;
  show &amp;quot;P a ⟶ Q b&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    with assms have &amp;quot;∀x. Q x&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;Q b&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_19c: &lt;br /&gt;
  assumes &amp;quot;P a ⟶ (∀x. Q x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P a ⟶ Q x&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix b&lt;br /&gt;
  show &amp;quot;P a ⟶ Q b&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    with assms have &amp;quot;∀x. Q x&amp;quot; by (rule mp)&lt;br /&gt;
    thus &amp;quot;Q b&amp;quot; by (rule allE)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 20. Demostrar&lt;br /&gt;
       {∀x y z. R x y ∧ R y z ⟶ R x z, &lt;br /&gt;
        ∀x. ¬(R x x)}&lt;br /&gt;
       ⊢ ∀x y. R x y ⟶ ¬(R y x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_20a: &lt;br /&gt;
  &amp;quot;⟦∀x y z. R x y ∧ R y z ⟶ R x z; ∀x. ¬(R x x)⟧ ⟹ ∀x y. R x y ⟶ ¬(R y x)&amp;quot;&lt;br /&gt;
by metis&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_20b: &lt;br /&gt;
  assumes &amp;quot;∀x y z. R x y ∧ R y z ⟶ R x z&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ¬(R x x)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∀x y. R x y ⟶ ¬(R y x)&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;R a b ⟶ ¬(R b a)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;R a b&amp;quot;&lt;br /&gt;
    show &amp;quot;¬(R b a)&amp;quot;&lt;br /&gt;
    proof &lt;br /&gt;
      assume &amp;quot;R b a&amp;quot;&lt;br /&gt;
      show False&lt;br /&gt;
      proof -&lt;br /&gt;
        have &amp;quot;R a b ∧ R b a&amp;quot; using `R a b` `R b a` ..&lt;br /&gt;
        have &amp;quot;∀y z. R a y ∧ R y z ⟶ R a z&amp;quot; using assms(1) ..&lt;br /&gt;
        hence &amp;quot;∀z. R a b ∧ R b z ⟶ R a z&amp;quot; ..&lt;br /&gt;
        hence &amp;quot;R a b ∧ R b a ⟶ R a a&amp;quot; ..&lt;br /&gt;
        hence &amp;quot;R a a&amp;quot; using `R a b ∧ R b a` ..&lt;br /&gt;
        have &amp;quot;¬(R a a)&amp;quot; using assms(2) ..&lt;br /&gt;
        thus False using `R a a` ..&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_20c: &lt;br /&gt;
  assumes &amp;quot;∀x y z. R x y ∧ R y z ⟶ R x z&amp;quot;&lt;br /&gt;
          &amp;quot;∀x. ¬(R x x)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∀x y. R x y ⟶ ¬(R y x)&amp;quot;&lt;br /&gt;
proof (rule allI)+&lt;br /&gt;
  fix a b&lt;br /&gt;
  show &amp;quot;R a b ⟶ ¬(R b a)&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;R a b&amp;quot;&lt;br /&gt;
    show &amp;quot;¬(R b a)&amp;quot;&lt;br /&gt;
    proof (rule notI)&lt;br /&gt;
      assume &amp;quot;R b a&amp;quot;&lt;br /&gt;
      show False&lt;br /&gt;
      proof -&lt;br /&gt;
        have &amp;quot;R a b ∧ R b a&amp;quot; using `R a b` `R b a` by (rule conjI)&lt;br /&gt;
        have &amp;quot;∀y z. R a y ∧ R y z ⟶ R a z&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
        hence &amp;quot;∀z. R a b ∧ R b z ⟶ R a z&amp;quot; by (rule allE)&lt;br /&gt;
        hence &amp;quot;R a b ∧ R b a ⟶ R a a&amp;quot; by (rule allE)&lt;br /&gt;
        hence &amp;quot;R a a&amp;quot; using `R a b ∧ R b a` by (rule mp)&lt;br /&gt;
        have &amp;quot;¬(R a a)&amp;quot; using assms(2) by (rule allE)&lt;br /&gt;
        thus False using `R a a` by (rule notE)&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 21. Demostrar&lt;br /&gt;
     {∀x. P x ∨ Q x, ∃x. ¬(Q x), ∀x. R x ⟶ ¬(P x)} ⊢ ∃x. ¬(R x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_21a:&lt;br /&gt;
  &amp;quot;⟦∀x. P x ∨ Q x; ∃x. ¬(Q x); ∀x. R x ⟶ ¬(P x)⟧ ⟹ ∃x. ¬(R x)&amp;quot; &lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_21b:&lt;br /&gt;
  assumes &amp;quot;∀x. P x ∨ Q x&amp;quot; &lt;br /&gt;
          &amp;quot;∃x. ¬(Q x)&amp;quot; &lt;br /&gt;
          &amp;quot;∀x. R x ⟶ ¬(P x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. ¬(R x)&amp;quot; &lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;¬(Q a)&amp;quot; using assms(2) ..&lt;br /&gt;
  have &amp;quot;P a ∨ Q a&amp;quot; using assms(1) ..&lt;br /&gt;
  hence &amp;quot;P a&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    thus &amp;quot;P a&amp;quot; .&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;Q a&amp;quot;&lt;br /&gt;
    with `¬(Q a)` show &amp;quot;P a&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
  hence &amp;quot;¬¬(P a)&amp;quot; by (rule notnotI)&lt;br /&gt;
  have &amp;quot;R a ⟶ ¬(P a)&amp;quot; using assms(3) ..&lt;br /&gt;
  hence &amp;quot;¬(R a)&amp;quot; using `¬¬(P a)` by (rule mt)&lt;br /&gt;
  thus &amp;quot;∃x. ¬(R x)&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_21c:&lt;br /&gt;
  assumes &amp;quot;∀x. P x ∨ Q x&amp;quot; &lt;br /&gt;
          &amp;quot;∃x. ¬(Q x)&amp;quot; &lt;br /&gt;
          &amp;quot;∀x. R x ⟶ ¬(P x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x. ¬(R x)&amp;quot; &lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;¬(Q a)&amp;quot; using assms(2) by (rule exE)&lt;br /&gt;
  have &amp;quot;P a ∨ Q a&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
  hence &amp;quot;P a&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    thus &amp;quot;P a&amp;quot; by this&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;Q a&amp;quot;&lt;br /&gt;
    with `¬(Q a)` show &amp;quot;P a&amp;quot; by (rule notE)&lt;br /&gt;
  qed&lt;br /&gt;
  hence &amp;quot;¬¬(P a)&amp;quot; by (rule notnotI)&lt;br /&gt;
  have &amp;quot;R a ⟶ ¬(P a)&amp;quot; using assms(3) by (rule allE)&lt;br /&gt;
  hence &amp;quot;¬(R a)&amp;quot; using `¬¬(P a)` by (rule mt)&lt;br /&gt;
  thus &amp;quot;∃x. ¬(R x)&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 22. Demostrar&lt;br /&gt;
     {∀x. P x ⟶ Q x ∨ R x, ¬(∃x. P x ∧ R x)} ⊢ ∀x. P x ⟶ Q x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_22a:&lt;br /&gt;
  &amp;quot;⟦∀x. P x ⟶ Q x ∨ R x; ¬(∃x. P x ∧ R x)⟧ ⟹ ∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
by auto &lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_22b:&lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q x ∨ R x&amp;quot; &lt;br /&gt;
          &amp;quot;¬(∃x. P x ∧ R x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;P a ⟶ Q a&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    have &amp;quot;P a ⟶ Q a ∨ R a&amp;quot; using assms(1) ..&lt;br /&gt;
    hence &amp;quot;Q a ∨ R a&amp;quot; using `P a` ..&lt;br /&gt;
    thus &amp;quot;Q a&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;Q a&amp;quot;&lt;br /&gt;
      thus &amp;quot;Q a&amp;quot; .&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;R a&amp;quot;&lt;br /&gt;
      with `P a` have &amp;quot;P a ∧ R a&amp;quot; ..&lt;br /&gt;
      hence &amp;quot;∃x. P x ∧ R x&amp;quot; ..&lt;br /&gt;
      with assms(2) show &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_22c:&lt;br /&gt;
  assumes &amp;quot;∀x. P x ⟶ Q x ∨ R x&amp;quot; &lt;br /&gt;
          &amp;quot;¬(∃x. P x ∧ R x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. P x ⟶ Q x&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix a&lt;br /&gt;
  show &amp;quot;P a ⟶ Q a&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    have &amp;quot;P a ⟶ Q a ∨ R a&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
    hence &amp;quot;Q a ∨ R a&amp;quot; using `P a` by (rule mp)&lt;br /&gt;
    thus &amp;quot;Q a&amp;quot;&lt;br /&gt;
    proof (rule disjE)&lt;br /&gt;
      assume &amp;quot;Q a&amp;quot;&lt;br /&gt;
      thus &amp;quot;Q a&amp;quot; by this&lt;br /&gt;
    next&lt;br /&gt;
      assume &amp;quot;R a&amp;quot;&lt;br /&gt;
      with `P a` have &amp;quot;P a ∧ R a&amp;quot; by (rule conjI)&lt;br /&gt;
      hence &amp;quot;∃x. P x ∧ R x&amp;quot; by (rule exI)&lt;br /&gt;
      with assms(2) show &amp;quot;Q a&amp;quot; by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 23. Demostrar&lt;br /&gt;
     ∃x y. R x y ∨ R y x ⊢ ∃x y. R x y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_23a:&lt;br /&gt;
  &amp;quot;∃x y. R x y ∨ R y x ⟹ ∃x y. R x y&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_23b:&lt;br /&gt;
  assumes &amp;quot;∃x y. R x y ∨ R y x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x y. R x y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. R a y ∨ R y a&amp;quot; using assms ..&lt;br /&gt;
  then obtain b where &amp;quot;R a b ∨ R b a&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃x y. R x y&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;R a b&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃y. R a y&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;∃ x y. R x y&amp;quot; ..&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;R b a&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃y. R b y&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;∃ x y. R x y&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_23c:&lt;br /&gt;
  assumes &amp;quot;∃x y. R x y ∨ R y x&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃x y. R x y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. R a y ∨ R y a&amp;quot; using assms by (rule exE)&lt;br /&gt;
  then obtain b where &amp;quot;R a b ∨ R b a&amp;quot; by (rule exE)&lt;br /&gt;
  thus &amp;quot;∃x y. R x y&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;R a b&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃y. R a y&amp;quot; by (rule exI)&lt;br /&gt;
    thus &amp;quot;∃ x y. R x y&amp;quot; by (rule exI)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;R b a&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃y. R b y&amp;quot; by (rule exI)&lt;br /&gt;
    thus &amp;quot;∃ x y. R x y&amp;quot; by (rule exI)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 24. Demostrar&lt;br /&gt;
       (∃x. ∀y. P x y) ⟶ (∀y. ∃x. P x y)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_24a: &amp;quot;(∃x. ∀y. P x y) ⟶ (∀y. ∃x. P x y)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_24b: &amp;quot;(∃x. ∀y. P x y) ⟶ (∀y. ∃x. P x y)&amp;quot;&lt;br /&gt;
proof &lt;br /&gt;
  assume &amp;quot;∃x. ∀y. P x y&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;∀y. P a y&amp;quot; ..&lt;br /&gt;
  show &amp;quot;∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix b&lt;br /&gt;
    have &amp;quot;P a b&amp;quot; using `∀y. P a y` ..&lt;br /&gt;
    thus &amp;quot;∃x. P x b&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_24c: &amp;quot;(∃x. ∀y. P x y) ⟶ (∀y. ∃x. P x y)&amp;quot;&lt;br /&gt;
proof (rule impI)&lt;br /&gt;
  assume &amp;quot;∃x. ∀y. P x y&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;∀y. P a y&amp;quot; by (rule exE)&lt;br /&gt;
  show &amp;quot;∀y. ∃x. P x y&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix b&lt;br /&gt;
    have &amp;quot;P a b&amp;quot; using `∀y. P a y` by (rule allE)&lt;br /&gt;
    thus &amp;quot;∃x. P x b&amp;quot; by (rule exI)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 25. Demostrar&lt;br /&gt;
       (∀x. P x ⟶ Q) ⟷ ((∃x. P x) ⟶ Q)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_25a: &amp;quot;(∀x. P x ⟶ Q) ⟷ ((∃x. P x) ⟶ Q)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_25b: &amp;quot;(∀x. P x ⟶ Q) ⟷ ((∃x. P x) ⟶ Q)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;∀x. P x ⟶ Q&amp;quot;&lt;br /&gt;
  show &amp;quot;(∃x. P x) ⟶ Q&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
    then obtain a where &amp;quot;P a&amp;quot; ..&lt;br /&gt;
    have &amp;quot;P a ⟶ Q&amp;quot; using `∀x. P x ⟶ Q` ..&lt;br /&gt;
    thus &amp;quot;Q&amp;quot; using `P a` ..&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;(∃x. P x) ⟶ Q&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. P x ⟶ Q&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix b&lt;br /&gt;
    show &amp;quot;P b ⟶ Q&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;P b&amp;quot;&lt;br /&gt;
      hence &amp;quot;∃x. P x&amp;quot; ..&lt;br /&gt;
      with `(∃x. P x) ⟶ Q` show &amp;quot;Q&amp;quot; ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_25c: &amp;quot;(∀x. P x ⟶ Q) ⟷ ((∃x. P x) ⟶ Q)&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;∀x. P x ⟶ Q&amp;quot;&lt;br /&gt;
  show &amp;quot;(∃x. P x) ⟶ Q&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
    then obtain a where &amp;quot;P a&amp;quot; by (rule exE)&lt;br /&gt;
    have &amp;quot;P a ⟶ Q&amp;quot; using `∀x. P x ⟶ Q` by (rule allE)&lt;br /&gt;
    thus &amp;quot;Q&amp;quot; using `P a` by (rule mp)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;(∃x. P x) ⟶ Q&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. P x ⟶ Q&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix b&lt;br /&gt;
    show &amp;quot;P b ⟶ Q&amp;quot;&lt;br /&gt;
    proof (rule impI)&lt;br /&gt;
      assume &amp;quot;P b&amp;quot;&lt;br /&gt;
      hence &amp;quot;∃x. P x&amp;quot; by (rule exI)&lt;br /&gt;
      with `(∃x. P x) ⟶ Q` show &amp;quot;Q&amp;quot; by (rule mp)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 26. Demostrar&lt;br /&gt;
       ((∀x. P x) ∧ (∀x. Q x)) ⟷ (∀x. P x ∧ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_26a: &amp;quot;((∀x. P x) ∧ (∀x. Q x)) ⟷ (∀x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_26b: &amp;quot;((∀x. P x) ∧ (∀x. Q x)) ⟷ (∀x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;(∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;∀x. P x&amp;quot; using `(∀x. P x) ∧ (∀x. Q x)` ..&lt;br /&gt;
    have &amp;quot;∀x. Q x&amp;quot; using `(∀x. P x) ∧ (∀x. Q x)` ..&lt;br /&gt;
    hence &amp;quot;Q a&amp;quot; .. &lt;br /&gt;
    have &amp;quot;P a&amp;quot; using `∀x. P x` ..&lt;br /&gt;
    thus &amp;quot;P a ∧ Q a&amp;quot; using `Q a` ..&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  have &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P a ∧ Q a&amp;quot; using `∀x. P x ∧ Q x` .. &lt;br /&gt;
    thus &amp;quot;P a&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
  moreover have &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P a ∧ Q a&amp;quot; using `∀x. P x ∧ Q x` .. &lt;br /&gt;
    thus &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
  ultimately show &amp;quot;(∀x. P x) ∧ (∀x. Q x)&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_26c: &amp;quot;((∀x. P x) ∧ (∀x. Q x)) = (∀x. P x ∧ Q x)&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;(∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  show &amp;quot;∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;∀x. P x&amp;quot; using `(∀x. P x) ∧ (∀x. Q x)` by (rule conjunct1)&lt;br /&gt;
    have &amp;quot;∀x. Q x&amp;quot; using `(∀x. P x) ∧ (∀x. Q x)` by (rule conjunct2)&lt;br /&gt;
    hence &amp;quot;Q a&amp;quot; by (rule allE)&lt;br /&gt;
    have &amp;quot;P a&amp;quot; using `∀x. P x` by (rule allE)&lt;br /&gt;
    thus &amp;quot;P a ∧ Q a&amp;quot; using `Q a` by (rule conjI)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  have &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P a ∧ Q a&amp;quot; using `∀x. P x ∧ Q x` by (rule allE) &lt;br /&gt;
    thus &amp;quot;P a&amp;quot; by (rule conjunct1)&lt;br /&gt;
  qed&lt;br /&gt;
  moreover have &amp;quot;∀x. Q x&amp;quot;&lt;br /&gt;
  proof (rule allI)&lt;br /&gt;
    fix a&lt;br /&gt;
    have &amp;quot;P a ∧ Q a&amp;quot; using `∀x. P x ∧ Q x` by (rule allE) &lt;br /&gt;
    thus &amp;quot;Q a&amp;quot; by (rule conjunct2)&lt;br /&gt;
  qed&lt;br /&gt;
  ultimately show &amp;quot;(∀x. P x) ∧ (∀x. Q x)&amp;quot; by (rule conjI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 27. Demostrar o refutar&lt;br /&gt;
       ((∀x. P x) ∨ (∀x. Q x)) ⟷ (∀x. P x ∨ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_27: &amp;quot;((∀x. P x) ∨ (∀x. Q x)) ⟷ (∀x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
(*&lt;br /&gt;
Auto Quickcheck found a counterexample:&lt;br /&gt;
P = {a\&amp;lt;^isub&amp;gt;1}&lt;br /&gt;
Q = {a\&amp;lt;^isub&amp;gt;2}&lt;br /&gt;
*)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 28. Demostrar o refutar&lt;br /&gt;
       ((∃x. P x) ∨ (∃x. Q x)) ⟷ (∃x. P x ∨ Q x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_28a: &lt;br /&gt;
  &amp;quot;((∃x. P x) ∨ (∃x. Q x)) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_28b: &lt;br /&gt;
  &amp;quot;((∃x. P x) ∨ (∃x. Q x)) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  thus &amp;quot;∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
    then obtain a where &amp;quot;P a&amp;quot; ..&lt;br /&gt;
    hence &amp;quot;P a ∨ Q a&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;∃x. P x ∨ Q x&amp;quot; ..&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;∃x. Q x&amp;quot;&lt;br /&gt;
    then obtain a where &amp;quot;Q a&amp;quot; ..&lt;br /&gt;
    hence &amp;quot;P a ∨ Q a&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;∃x. P x ∨ Q x&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P a ∨ Q a&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃x. P x&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot; ..&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;Q a&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃x. Q x&amp;quot; ..&lt;br /&gt;
    thus &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot; ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_28c: &lt;br /&gt;
  &amp;quot;((∃x. P x) ∨ (∃x. Q x)) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  thus &amp;quot;∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;∃x. P x&amp;quot;&lt;br /&gt;
    then obtain a where &amp;quot;P a&amp;quot; by (rule exE)&lt;br /&gt;
    hence &amp;quot;P a ∨ Q a&amp;quot; by (rule disjI1)&lt;br /&gt;
    thus &amp;quot;∃x. P x ∨ Q x&amp;quot; by (rule exI)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;∃x. Q x&amp;quot;&lt;br /&gt;
    then obtain a where &amp;quot;Q a&amp;quot; by (rule exE)&lt;br /&gt;
    hence &amp;quot;P a ∨ Q a&amp;quot; by (rule disjI2)&lt;br /&gt;
    thus &amp;quot;∃x. P x ∨ Q x&amp;quot; by (rule exI)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;P a ∨ Q a&amp;quot; by (rule exE)&lt;br /&gt;
  thus &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;P a&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃x. P x&amp;quot; by (rule exI)&lt;br /&gt;
    thus &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot; by (rule disjI1)&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;Q a&amp;quot;&lt;br /&gt;
    hence &amp;quot;∃x. Q x&amp;quot; by (rule exI)&lt;br /&gt;
    thus &amp;quot;(∃x. P x) ∨ (∃x. Q x)&amp;quot; by (rule disjI2)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 29. Demostrar o refutar&lt;br /&gt;
       (∀x. ∃y. P x y) ⟶ (∃y. ∀x. P x y)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ejercicio_29: &lt;br /&gt;
  &amp;quot;(∀x. ∃y. P x y) ⟶ (∃y. ∀x. P x y)&amp;quot;&lt;br /&gt;
quickcheck&lt;br /&gt;
(*&lt;br /&gt;
Quickcheck found a counterexample:&lt;br /&gt;
&lt;br /&gt;
P = (λx. undefined)(a\&amp;lt;^isub&amp;gt; := {b}, b := {a})&lt;br /&gt;
*)&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 30. Demostrar o refutar&lt;br /&gt;
       (¬(∀x. P x)) ⟷ (∃x. ¬P x)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_30a: &lt;br /&gt;
  &amp;quot;(¬(∀x. P x)) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_30b: &lt;br /&gt;
  &amp;quot;(¬(∀x. P x)) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  assume &amp;quot;¬(∀x. P x)&amp;quot;&lt;br /&gt;
  show &amp;quot;∃x. ¬P x&amp;quot;&lt;br /&gt;
  proof (rule ccontr)&lt;br /&gt;
    assume &amp;quot;¬(∃x. ¬P x)&amp;quot;&lt;br /&gt;
    have &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      fix a&lt;br /&gt;
      show &amp;quot;P a&amp;quot;&lt;br /&gt;
      proof (rule ccontr)&lt;br /&gt;
        assume &amp;quot;¬P a&amp;quot;&lt;br /&gt;
        hence &amp;quot;∃x. ¬P x&amp;quot; ..&lt;br /&gt;
        with `¬(∃x. ¬P x)` show False ..&lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
    with `¬(∀x. P x)` show False ..&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. ¬P x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;¬P a&amp;quot; ..&lt;br /&gt;
  show &amp;quot;¬(∀x. P x)&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
    hence &amp;quot;P a&amp;quot; ..&lt;br /&gt;
    with `¬P a` show False ..&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_30c: &lt;br /&gt;
  &amp;quot;(¬(∀x. P x)) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
proof (rule iffI)&lt;br /&gt;
  assume &amp;quot;¬(∀x. P x)&amp;quot;&lt;br /&gt;
  show &amp;quot;∃x. ¬P x&amp;quot;&lt;br /&gt;
  proof (rule ccontr)&lt;br /&gt;
    assume &amp;quot;¬(∃x. ¬P x)&amp;quot;&lt;br /&gt;
    have &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
    proof (rule allI)&lt;br /&gt;
      fix a&lt;br /&gt;
      show &amp;quot;P a&amp;quot;&lt;br /&gt;
      proof (rule ccontr)&lt;br /&gt;
        assume &amp;quot;¬P a&amp;quot;&lt;br /&gt;
        hence &amp;quot;∃x. ¬P x&amp;quot; by (rule exI)&lt;br /&gt;
        with `¬(∃x. ¬P x)` show False by (rule notE) &lt;br /&gt;
      qed&lt;br /&gt;
    qed&lt;br /&gt;
    with `¬(∀x. P x)` show False by (rule notE)&lt;br /&gt;
  qed&lt;br /&gt;
next&lt;br /&gt;
  assume &amp;quot;∃x. ¬P x&amp;quot;&lt;br /&gt;
  then obtain a where &amp;quot;¬P a&amp;quot; by (rule exE)&lt;br /&gt;
  show &amp;quot;¬(∀x. P x)&amp;quot;&lt;br /&gt;
  proof (rule notI)&lt;br /&gt;
    assume &amp;quot;∀x. P x&amp;quot;&lt;br /&gt;
    hence &amp;quot;P a&amp;quot; by (rule allE)&lt;br /&gt;
    show False using `¬P a` `P a` by (rule notE)&lt;br /&gt;
  qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Ejercicios sobre igualdad *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 31. Demostrar o refutar&lt;br /&gt;
       P a ⟹ ∀x. x = a ⟶ P x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_31a:&lt;br /&gt;
  &amp;quot;P a ⟹ ∀x. x = a ⟶ P x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_31b:&lt;br /&gt;
  assumes &amp;quot;P a&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. x = a ⟶ P x&amp;quot;&lt;br /&gt;
proof&lt;br /&gt;
  fix b&lt;br /&gt;
  show &amp;quot;b = a ⟶ P b&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;b = a&amp;quot;&lt;br /&gt;
    thus &amp;quot;P b&amp;quot; using assms by (rule ssubst)&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_31c:&lt;br /&gt;
  assumes &amp;quot;P a&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∀x. x = a ⟶ P x&amp;quot;&lt;br /&gt;
proof (rule allI)&lt;br /&gt;
  fix b&lt;br /&gt;
  show &amp;quot;b = a ⟶ P b&amp;quot;&lt;br /&gt;
  proof (rule impI)&lt;br /&gt;
    assume &amp;quot;b = a&amp;quot;&lt;br /&gt;
    thus &amp;quot;P b&amp;quot; using assms by (rule ssubst)&lt;br /&gt;
  qed &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 32. Demostrar o refutar&lt;br /&gt;
       ∃x y. R x y ∨ R y x; ¬(∃x. R x x)⟧ ⟹ ∃x y. x ≠ y&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_32a:&lt;br /&gt;
  fixes R :: &amp;quot;&amp;#039;c ⇒ &amp;#039;c ⇒ bool&amp;quot;&lt;br /&gt;
  assumes &amp;quot;∃x y. R x y ∨ R y x&amp;quot;&lt;br /&gt;
          &amp;quot;¬(∃x. R x x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃(x::&amp;#039;c) y. x ≠ y&amp;quot;&lt;br /&gt;
using assms&lt;br /&gt;
by metis&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_32b:&lt;br /&gt;
  fixes R :: &amp;quot;&amp;#039;c ⇒ &amp;#039;c ⇒ bool&amp;quot;&lt;br /&gt;
  assumes &amp;quot;∃x y. R x y ∨ R y x&amp;quot;&lt;br /&gt;
          &amp;quot;¬(∃x. R x x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃(x::&amp;#039;c) y. x ≠ y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. R a y ∨ R y a&amp;quot; using assms(1) ..&lt;br /&gt;
  then obtain b where &amp;quot;R a b ∨ R b a&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;a ≠ b&amp;quot;&lt;br /&gt;
  proof&lt;br /&gt;
    assume &amp;quot;R a b&amp;quot;&lt;br /&gt;
    show &amp;quot;a ≠ b&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;a = b&amp;quot;&lt;br /&gt;
      hence &amp;quot;R b b&amp;quot; using `R a b` by (rule subst)&lt;br /&gt;
      hence &amp;quot;∃x. R x x&amp;quot; ..&lt;br /&gt;
      with assms(2) show False ..&lt;br /&gt;
    qed&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;R b a&amp;quot;&lt;br /&gt;
    show &amp;quot;a ≠ b&amp;quot;&lt;br /&gt;
    proof&lt;br /&gt;
      assume &amp;quot;a = b&amp;quot;&lt;br /&gt;
      hence &amp;quot;R a a&amp;quot; using `R b a` by (rule ssubst)&lt;br /&gt;
      hence &amp;quot;∃x. R x x&amp;quot; ..&lt;br /&gt;
      with assms(2) show False ..&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
  hence &amp;quot;∃y. a ≠ y&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃(x::&amp;#039;c) y. x ≠ y&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_32c:&lt;br /&gt;
  fixes R :: &amp;quot;&amp;#039;c ⇒ &amp;#039;c ⇒ bool&amp;quot;&lt;br /&gt;
  assumes &amp;quot;∃x y. R x y ∨ R y x&amp;quot;&lt;br /&gt;
          &amp;quot;¬(∃x. R x x)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃(x::&amp;#039;c) y. x ≠ y&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  obtain a where &amp;quot;∃y. R a y ∨ R y a&amp;quot; using assms(1) by (rule exE)&lt;br /&gt;
  then obtain b where &amp;quot;R a b ∨ R b a&amp;quot; by (rule exE)&lt;br /&gt;
  hence &amp;quot;a ≠ b&amp;quot;&lt;br /&gt;
  proof (rule disjE)&lt;br /&gt;
    assume &amp;quot;R a b&amp;quot;&lt;br /&gt;
    show &amp;quot;a ≠ b&amp;quot;&lt;br /&gt;
    proof (rule notI)&lt;br /&gt;
      assume &amp;quot;a = b&amp;quot;&lt;br /&gt;
      hence &amp;quot;R b b&amp;quot; using `R a b` by (rule subst)&lt;br /&gt;
      hence &amp;quot;∃x. R x x&amp;quot; by (rule exI)&lt;br /&gt;
      with assms(2) show False by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
  next&lt;br /&gt;
    assume &amp;quot;R b a&amp;quot;&lt;br /&gt;
    show &amp;quot;a ≠ b&amp;quot;&lt;br /&gt;
    proof (rule notI)&lt;br /&gt;
      assume &amp;quot;a = b&amp;quot;&lt;br /&gt;
      hence &amp;quot;R a a&amp;quot; using `R b a` by (rule ssubst)&lt;br /&gt;
      hence &amp;quot;∃x. R x x&amp;quot; by (rule exI)&lt;br /&gt;
      with assms(2) show False by (rule notE)&lt;br /&gt;
    qed&lt;br /&gt;
  qed&lt;br /&gt;
  hence &amp;quot;∃y. a ≠ y&amp;quot; by (rule exI)&lt;br /&gt;
  thus &amp;quot;∃(x::&amp;#039;c) y. x ≠ y&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 33. Demostrar o refutar&lt;br /&gt;
     {∀x. P a x x, &lt;br /&gt;
      ∀x y z. P x y z ⟶ P (f x) y (f z)} &lt;br /&gt;
     ⊢ P (f a) a (f a)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_33a:&lt;br /&gt;
  &amp;quot;⟦∀x. P a x x; ∀x y z. P x y z ⟶ P (f x) y (f z)⟧ ⟹ P (f a) a (f a)&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructura es›&lt;br /&gt;
lemma ejercicio_33b:&lt;br /&gt;
  assumes &amp;quot;∀x. P a x x&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y z. P x y z ⟶ P (f x) y (f z)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;P (f a) a (f a)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P a a a&amp;quot; using assms(1) ..&lt;br /&gt;
  have &amp;quot;∀y z. P a y z ⟶ P (f a) y (f z)&amp;quot; using assms(2) ..&lt;br /&gt;
  hence &amp;quot;∀z. P a a z ⟶ P (f a) a (f z)&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;P a a a ⟶ P (f a) a (f a)&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;P (f a) a (f a)&amp;quot; using `P a a a` ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_33c:&lt;br /&gt;
  assumes &amp;quot;∀x. P a x x&amp;quot;&lt;br /&gt;
          &amp;quot;∀x y z. P x y z ⟶ P (f x) y (f z)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;P (f a) a (f a)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P a a a&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
  have &amp;quot;∀y z. P a y z ⟶ P (f a) y (f z)&amp;quot; using assms(2) by (rule allE)&lt;br /&gt;
  hence &amp;quot;∀z. P a a z ⟶ P (f a) a (f z)&amp;quot; by (rule allE)&lt;br /&gt;
  hence &amp;quot;P a a a ⟶ P (f a) a (f a)&amp;quot; by (rule allE)&lt;br /&gt;
  thus &amp;quot;P (f a) a (f a)&amp;quot; using `P a a a` by (rule mp)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 34. Demostrar o refutar&lt;br /&gt;
     {∀x. P a x x, &lt;br /&gt;
      ∀x y z. P x y z ⟶ P (f x) y (f z)⟧&lt;br /&gt;
     ⊢ ∃z. P (f a) z (f (f a))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_34a:&lt;br /&gt;
  &amp;quot;⟦∀x. P a x x; ∀x y z. P x y z ⟶ P (f x) y (f z)⟧&lt;br /&gt;
   ⟹ ∃z. P (f a) z (f (f a))&amp;quot;&lt;br /&gt;
by metis&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructura es›&lt;br /&gt;
lemma ejercicio_34b:&lt;br /&gt;
  assumes &amp;quot;∀x. P a x x&amp;quot; &lt;br /&gt;
          &amp;quot;∀x y z. P x y z ⟶ P (f x) y (f z)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃z. P (f a) z (f (f a))&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P a (f a) (f a)&amp;quot; using assms(1) ..&lt;br /&gt;
  have &amp;quot;∀y z. P a y z ⟶ P (f a) y (f z)&amp;quot; using assms(2) ..&lt;br /&gt;
  hence &amp;quot;∀z. P a (f a) z ⟶ P (f a) (f a) (f z)&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;P a (f a) (f a) ⟶ P (f a) (f a) (f (f a))&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;P (f a) (f a) (f (f a))&amp;quot; using `P a (f a) (f a)` ..&lt;br /&gt;
  thus &amp;quot;∃z. P (f a) z (f (f a))&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_34c:&lt;br /&gt;
  assumes &amp;quot;∀x. P a x x&amp;quot; &lt;br /&gt;
          &amp;quot;∀x y z. P x y z ⟶ P (f x) y (f z)&amp;quot;&lt;br /&gt;
  shows   &amp;quot;∃z. P (f a) z (f (f a))&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;P a (f a) (f a)&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
  have &amp;quot;∀y z. P a y z ⟶ P (f a) y (f z)&amp;quot; using assms(2) by (rule allE)&lt;br /&gt;
  hence &amp;quot;∀z. P a (f a) z ⟶ P (f a) (f a) (f z)&amp;quot; by (rule allE)&lt;br /&gt;
  hence &amp;quot;P a (f a) (f a) ⟶ P (f a) (f a) (f (f a))&amp;quot; by (rule allE)&lt;br /&gt;
  hence &amp;quot;P (f a) (f a) (f (f a))&amp;quot; using `P a (f a) (f a)` by (rule mp)&lt;br /&gt;
  thus &amp;quot;∃z. P (f a) z (f (f a))&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 35. Demostrar o refutar&lt;br /&gt;
     {∀y. Q a y, &lt;br /&gt;
      ∀x y. Q x y ⟶ Q (s x) (s y)} &lt;br /&gt;
     ⊢ ∃z. Qa z ∧ Q z (s (s a))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_35a:&lt;br /&gt;
  &amp;quot;⟦∀y. Q a y; ∀x y. Q x y ⟶ Q (s x) (s y)⟧ ⟹ ∃z. Q a z ∧ Q z (s (s a))&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructura es›&lt;br /&gt;
lemma ejercicio_35b:&lt;br /&gt;
  assumes &amp;quot;∀y. Q a y&amp;quot; &lt;br /&gt;
          &amp;quot;∀x y. Q x y ⟶ Q (s x) (s y)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∃z. Q a z ∧ Q z (s (s a))&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;Q a (s a)&amp;quot; using assms(1) ..&lt;br /&gt;
  have &amp;quot;∀y. Q a y ⟶ Q (s a) (s y)&amp;quot; using assms(2) ..&lt;br /&gt;
  hence &amp;quot;Q a (s a) ⟶ Q (s a) (s (s a))&amp;quot; ..&lt;br /&gt;
  hence &amp;quot;Q (s a) (s (s a))&amp;quot; using `Q a (s a)` ..&lt;br /&gt;
  with `Q a (s a)` have &amp;quot;Q a (s a) ∧ Q (s a) (s (s a))&amp;quot; ..&lt;br /&gt;
  thus &amp;quot;∃z. Q a z ∧ Q z (s (s a))&amp;quot; ..&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración detallada es›&lt;br /&gt;
lemma ejercicio_35c:&lt;br /&gt;
  assumes &amp;quot;∀y. Q a y&amp;quot; &lt;br /&gt;
          &amp;quot;∀x y. Q x y ⟶ Q (s x) (s y)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;∃z. Q a z ∧ Q z (s (s a))&amp;quot;&lt;br /&gt;
proof - &lt;br /&gt;
  have &amp;quot;Q a (s a)&amp;quot; using assms(1) by (rule allE)&lt;br /&gt;
  have &amp;quot;∀y. Q a y ⟶ Q (s a) (s y)&amp;quot; using assms(2) by (rule allE)&lt;br /&gt;
  hence &amp;quot;Q a (s a) ⟶ Q (s a) (s (s a))&amp;quot; by (rule allE)&lt;br /&gt;
  hence &amp;quot;Q (s a) (s (s a))&amp;quot; using `Q a (s a)` by (rule mp)&lt;br /&gt;
  with `Q a (s a)` have &amp;quot;Q a (s a) ∧ Q (s a) (s (s a))&amp;quot; by (rule conjI)&lt;br /&gt;
  thus &amp;quot;∃z. Q a z ∧ Q z (s (s a))&amp;quot; by (rule exI)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 36. Demostrar o refutar&lt;br /&gt;
     {x = f x, odd (f x)} ⊢ odd x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_36a:&lt;br /&gt;
  &amp;quot;⟦x = f x; odd (f x)⟧ ⟹ odd x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es›&lt;br /&gt;
lemma ejercicio_36b:&lt;br /&gt;
  &amp;quot;⟦x = f x; odd (f x)⟧ ⟹ odd x&amp;quot;&lt;br /&gt;
by (rule ssubst)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_36c:&lt;br /&gt;
  assumes &amp;quot;x = f x&amp;quot; &lt;br /&gt;
          &amp;quot;odd (f x)&amp;quot; &lt;br /&gt;
  shows   &amp;quot;odd x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;odd x&amp;quot; using assms by (rule ssubst)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 37. Demostrar o refutar&lt;br /&gt;
     {x = f x, triple (f x) (f x) x} ⊢ triple x x x&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración automática es›&lt;br /&gt;
lemma ejercicio_37a:&lt;br /&gt;
  &amp;quot;⟦x = f x; triple (f x) (f x) x⟧ ⟹ triple x x x&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración semiautomática es›&lt;br /&gt;
lemma ejercicio_37b:&lt;br /&gt;
  &amp;quot;⟦x = f x; triple (f x) (f x) x⟧ ⟹ triple x x x&amp;quot;&lt;br /&gt;
by (rule ssubst)&lt;br /&gt;
&lt;br /&gt;
― ‹La demostración estructurada es›&lt;br /&gt;
lemma ejercicio_37c:&lt;br /&gt;
  assumes &amp;quot;x = f x&amp;quot; &lt;br /&gt;
          &amp;quot;triple (f x) (f x) x&amp;quot; &lt;br /&gt;
  shows   &amp;quot;triple x x x&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  show &amp;quot;triple x x x&amp;quot; using assms by (rule ssubst)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_7&amp;diff=577</id>
		<title>Sol 7</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Sol_7&amp;diff=577"/>
		<updated>2019-04-20T12:03:22Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
theory R7_sol&lt;br /&gt;
&lt;br /&gt;
imports Main &lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
  El objetivo de esta relación es escribir demostraciones usando sólo&lt;br /&gt;
  las reglas básicas de deducción natural de la lógica proposicional y&lt;br /&gt;
  los métodos rule, erule, frule, drule y assumption.&lt;br /&gt;
&lt;br /&gt;
  Las reglas básicas de la deducción natural son las siguientes:&lt;br /&gt;
  · conjI:          ⟦P; Q⟧ ⟹ P ∧ Q&lt;br /&gt;
  · conjunct1:      P ∧ Q ⟹ P&lt;br /&gt;
  · conjunct2:      P ∧ Q ⟹ Q&lt;br /&gt;
  · conjE:          ⟦P ∧ Q; ⟦P; Q⟧ ⟹ R⟧ ⟹ R&lt;br /&gt;
  · notE:           ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  · notI:           (P ⟹ False) ⟹ ¬P&lt;br /&gt;
  · mp:             ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
  · mt:             ⟦F ⟶ G; ¬G⟧ ⟹ ¬F &lt;br /&gt;
  · impI:           (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
  · impE:           ⟦P ⟶ Q; P; Q ⟹ R⟧ ⟹ R&lt;br /&gt;
  · disjI1:         P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2:         Q ⟹ P ∨ Q&lt;br /&gt;
  · disjE:          ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
  · FalseE:         False ⟹ P&lt;br /&gt;
  · iffI:           ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P = Q&lt;br /&gt;
  · iffD1:          ⟦Q = P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2:          ⟦P = Q; Q⟧ ⟹ P&lt;br /&gt;
  · iffE:           ⟦P = Q; ⟦P ⟶ Q; Q ⟶ P⟧ ⟹ R⟧ ⟹ R&lt;br /&gt;
  · notnotD:        ¬¬ P ⟹ P&lt;br /&gt;
  · not_not:        P = ¬¬P&lt;br /&gt;
  · ccontr:         (¬P ⟹ False) ⟹ P&lt;br /&gt;
  · excluded_midle: ¬P ∨ P&lt;br /&gt;
  · classical:      (¬ P ⟹ P) ⟹ P&lt;br /&gt;
  · contrapos_nn    ⟦¬Q; P ⟹ Q⟧ ⟹ ¬P&lt;br /&gt;
  --------------------------------------------------------------------- &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se usarán las reglas notnotI y mt que demostramos a continuación.&lt;br /&gt;
  *}&lt;br /&gt;
&lt;br /&gt;
lemma notnotI: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
  by auto&lt;br /&gt;
&lt;br /&gt;
section {* Implicaciones *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 1. Demostrar&lt;br /&gt;
       p ⟶ q, p ⊢ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej1a: &amp;quot;⟦p ⟶ q; p⟧ ⟹ q&amp;quot; &lt;br /&gt;
  apply (erule mp)   (* p ⟹ p *)&lt;br /&gt;
   apply assumption  (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej1b: &amp;quot;⟦p ⟶ q; p⟧ ⟹ q&amp;quot; &lt;br /&gt;
  apply (erule mp, assumption)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej1c: &amp;quot;⟦p ⟶ q; p⟧ ⟹ q&amp;quot; &lt;br /&gt;
  by (erule mp, assumption)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 2. Demostrar&lt;br /&gt;
     p ⟶ q, q ⟶ r, p ⊢ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej2a: &amp;quot;⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (erule mp)    (* ⟦p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
    apply (erule mp)  (* p ⟹ p *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
lemma ej2b: &amp;quot;⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (erule mp)+  (* p ⟹ p *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done  &lt;br /&gt;
&lt;br /&gt;
lemma ej2c: &amp;quot;⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply ((erule mp)+, assumption) &lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej2d: &amp;quot;⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  by ((erule mp)+, assumption) &lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 3. Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r), p ⟶ q, p ⊢ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej3a: &amp;quot;⟦p ⟶ (q ⟶ r); p ⟶ q; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp)   (* ⟦p ⟶ q; p⟧ ⟹ p&lt;br /&gt;
                        ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption  (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *) &lt;br /&gt;
  apply (drule mp)   (* ⟦p; q ⟶ r⟧ ⟹ p&lt;br /&gt;
                        ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply assumption  (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)   (* ⟦p; q⟧ ⟹ q&lt;br /&gt;
                        ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption  (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej3b: &amp;quot;⟦p ⟶ (q ⟶ r); p ⟶ q; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp, assumption) (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp, assumption) (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp, assumption) (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption             (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej3c: &amp;quot;⟦p ⟶ (q ⟶ r); p ⟶ q; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp, assumption)+ (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption              (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej3d: &amp;quot;⟦p ⟶ (q ⟶ r); p ⟶ q; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp, assumption+)+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej3e: &amp;quot;⟦p ⟶ (q ⟶ r); p ⟶ q; p⟧ ⟹ r&amp;quot;&lt;br /&gt;
  by (drule mp, assumption+)+&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 4. Demostrar&lt;br /&gt;
     p ⟶ q, q ⟶ r ⊢ p ⟶ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej4a: &amp;quot;⟦p ⟶ q; q ⟶ r⟧ ⟹ p ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)   (* ⟦p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)   (* p ⟹ p *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej4b: &amp;quot;⟦p ⟶ q; q ⟶ r⟧ ⟹ p ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)+  (* p ⟹ p *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 5. Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r) ⊢ q ⟶ (p ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej5a: &amp;quot;p ⟶ (q ⟶ r) ⟹ q ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)   (* ⟦p ⟶ q ⟶ r; q⟧ ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)   (* ⟦p ⟶ q ⟶ r; q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE)  (* ⟦q; p⟧ ⟹ p&lt;br /&gt;
                         ⟦q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption   (* ⟦q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE)  (* ⟦q; p⟧ ⟹ q&lt;br /&gt;
                         ⟦q; p; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption   (* ⟦q; p; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done  &lt;br /&gt;
  &lt;br /&gt;
lemma ej5b: &amp;quot;p ⟶ (q ⟶ r) ⟹ q ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)               (* ⟦p ⟶ q ⟶ r; q⟧ ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)               (* ⟦p ⟶ q ⟶ r; q; p⟧ ⟹ r *) &lt;br /&gt;
  apply (erule impE, assumption)  (* ⟦q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE, assumption+) (* *)&lt;br /&gt;
  done  &lt;br /&gt;
  &lt;br /&gt;
lemma ej5c: &amp;quot;p ⟶ (q ⟶ r) ⟹ q ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+              (* ⟦p ⟶ q ⟶ r; q; p⟧ ⟹ r *) &lt;br /&gt;
  apply (erule impE, assumption)  (* ⟦q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE, assumption+) (* *)&lt;br /&gt;
  done  &lt;br /&gt;
  &lt;br /&gt;
lemma ej5d: &amp;quot;p ⟶ (q ⟶ r) ⟹ q ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+                (* ⟦p ⟶ q ⟶ r; q; p⟧ ⟹ r *) &lt;br /&gt;
  apply (erule impE, assumption+)+  (* ⟦q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  done  &lt;br /&gt;
  &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 6. Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r) ⊢ (p ⟶ q) ⟶ (p ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej6a: &amp;quot;p ⟶ (q ⟶ r) ⟹ (p ⟶ q) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)   (* ⟦p ⟶ q ⟶ r; p ⟶ q⟧ ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)   (* ⟦p ⟶ q ⟶ r; p ⟶ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE)  (* ⟦p ⟶ q; p⟧ ⟹ p&lt;br /&gt;
                         ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption   (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE)  (* ⟦p; q ⟶ r⟧ ⟹ p&lt;br /&gt;
                         ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply assumption   (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE)  (* ⟦p; q⟧ ⟹ q&lt;br /&gt;
                         ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption   (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej6b: &amp;quot;p ⟶ (q ⟶ r) ⟹ (p ⟶ q) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)               (* ⟦p ⟶ q ⟶ r; p ⟶ q⟧ ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)               (* ⟦p ⟶ q ⟶ r; p ⟶ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE, assumption)  (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE, assumption)  (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE, assumption+) (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej6c: &amp;quot;p ⟶ (q ⟶ r) ⟹ (p ⟶ q) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+               (* ⟦p ⟶ q ⟶ r; p ⟶ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule impE, assumption+)+ (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 7. Demostrar&lt;br /&gt;
     p ⊢ q ⟶ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej7a: &amp;quot;p ⟹ q ⟶ p&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦p; q⟧ ⟹ p *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7b: &amp;quot;p ⟹ q ⟶ p&amp;quot;&lt;br /&gt;
  apply (rule impI, assumption)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 8. Demostrar&lt;br /&gt;
     ⊢ p ⟶ (q ⟶ p)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej8a: &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* p ⟹ q ⟶ p *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p; q⟧ ⟹ p *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej8b: &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
  apply (rule impI)+  (* ⟦p; q⟧ ⟹ p *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej8c: &amp;quot;p ⟶ (q ⟶ p)&amp;quot;&lt;br /&gt;
  by (rule impI)+ &lt;br /&gt;
&lt;br /&gt;
text {* ---------------------------------------------------------------&lt;br /&gt;
  Ejercicio 9. Demostrar&lt;br /&gt;
     p ⟶ q ⊢ (q ⟶ r) ⟶ (p ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej9a: &amp;quot;p ⟶ q ⟹ (q ⟶ r) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI) (* ⟦p ⟶ q; q ⟶ r⟧ ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI) (* ⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)  (* ⟦p ⟶ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule mp)  (* p ⟹ p *)&lt;br /&gt;
  apply assumption  (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej9b: &amp;quot;p ⟶ q ⟹ (q ⟶ r) ⟶ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+ (* ⟦p ⟶ q; q ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)+  (* p ⟹ p *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 10. Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ (r ⟶ s)) ⊢ r ⟶ (q ⟶ (p ⟶ s))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej10a: &amp;quot;p ⟶ (q ⟶ (r ⟶ s)) ⟹ r ⟶ (q ⟶ (p ⟶ s))&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r ⟶ s; r⟧ ⟹ q ⟶ p ⟶ s *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r ⟶ s; r; q⟧ ⟹ p ⟶ s *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r ⟶ s; r; q; p⟧ ⟹ s *)&lt;br /&gt;
  apply (drule mp)   (* ⟦r; q; p⟧ ⟹ p&lt;br /&gt;
                        ⟦r; q; p; q ⟶ r ⟶ s⟧ ⟹ s *)&lt;br /&gt;
   apply assumption  (* ⟦r; q; p; q ⟶ r ⟶ s⟧ ⟹ s *)&lt;br /&gt;
  apply (drule mp)   (* ⟦r; q; p⟧ ⟹ q&lt;br /&gt;
                        ⟦r; q; p; r ⟶ s⟧ ⟹ s *)&lt;br /&gt;
   apply assumption  (* ⟦r; q; p; r ⟶ s⟧ ⟹ s *)&lt;br /&gt;
  apply (erule mp)   (* ⟦r; q; p⟧ ⟹ r *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej10b: &amp;quot;p ⟶ (q ⟶ (r ⟶ s)) ⟹ r ⟶ (q ⟶ (p ⟶ s))&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r ⟶ s; r⟧ ⟹ q ⟶ p ⟶ s *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r ⟶ s; r; q⟧ ⟹ p ⟶ s *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r ⟶ s; r; q; p⟧ ⟹ s *)&lt;br /&gt;
  apply (drule mp, assumption)  (* ⟦r; q; p; q ⟶ r ⟶ s⟧ ⟹ s *)&lt;br /&gt;
  apply (drule mp, assumption)  (* ⟦r; q; p; r ⟶ s⟧ ⟹ s *)&lt;br /&gt;
  apply (erule mp, assumption)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej10c: &amp;quot;p ⟶ (q ⟶ (r ⟶ s)) ⟹ r ⟶ (q ⟶ (p ⟶ s))&amp;quot;&lt;br /&gt;
  apply (rule impI)+  (* ⟦p ⟶ q ⟶ r ⟶ s; r; q; p⟧ ⟹ s *)&lt;br /&gt;
  apply (drule mp, assumption+)+  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 11. Demostrar&lt;br /&gt;
     ⊢ (p ⟶ (q ⟶ r)) ⟶ ((p ⟶ q) ⟶ (p ⟶ r))&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej11a: &amp;quot;(p ⟶ (q ⟶ r)) ⟶ ((p ⟶ q) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* p ⟶ q ⟶ r ⟹ (p ⟶ q) ⟶ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r; p ⟶ q⟧ ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p ⟶ q ⟶ r; p ⟶ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)   (* ⟦p ⟶ q; p⟧ ⟹ p&lt;br /&gt;
                        ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption  (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)   (* ⟦p; q ⟶ r⟧ ⟹ p&lt;br /&gt;
                        ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply assumption  (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)   (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej11b: &amp;quot;(p ⟶ (q ⟶ r)) ⟶ ((p ⟶ q) ⟶ (p ⟶ r))&amp;quot;&lt;br /&gt;
  apply (rule impI)+             (* ⟦p ⟶ q ⟶ r; p ⟶ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp, assumption+)+ (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 12. Demostrar&lt;br /&gt;
     (p ⟶ q) ⟶ r ⊢ p ⟶ (q ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej12a: &amp;quot;(p ⟶ q) ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* ⟦(p ⟶ q) ⟶ r; p⟧ ⟹ q ⟶ r *)&lt;br /&gt;
  apply (rule impI)  (* ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)   (* ⟦p; q⟧ ⟹ p ⟶ q&lt;br /&gt;
                        ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply (rule impI)  (* ⟦p; q; p⟧ ⟹ q&lt;br /&gt;
                        ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption  (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption   (* *)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
lemma ej12b: &amp;quot;(p ⟶ q) ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+  (* ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)    (* ⟦p; q⟧ ⟹ p ⟶ q&lt;br /&gt;
                         ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply (rule impI)   (* ⟦p; q; p⟧ ⟹ q&lt;br /&gt;
                        ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption+  (* *)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
lemma ej12c: &amp;quot;(p ⟶ q) ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+  (* ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)    (* ⟦p; q⟧ ⟹ p ⟶ q&lt;br /&gt;
                         ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply (rule impI,&lt;br /&gt;
         assumption+) (* *)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
lemma ej12e: &amp;quot;(p ⟶ q) ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+                 (* ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (rule_tac P=&amp;quot;p ⟶ q&amp;quot; in mp) &lt;br /&gt;
                         (* ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ (p ⟶ q) ⟶ r&lt;br /&gt;
                            ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ p ⟶ q *)&lt;br /&gt;
   apply assumption      (* ⟦(p ⟶ q) ⟶ r; p; q⟧ ⟹ p ⟶ q *)&lt;br /&gt;
  apply (rule impI)      (* ⟦(p ⟶ q) ⟶ r; p; q; p⟧ ⟹ q *)&lt;br /&gt;
  apply assumption       (* *)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
section {* Conjunciones *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 13. Demostrar&lt;br /&gt;
     p, q ⊢  p ∧ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej13: &amp;quot;⟦p; q⟧ ⟹ p ∧ q&amp;quot;&lt;br /&gt;
  apply (rule conjI)   (* ⟦p; q⟧ ⟹ p &lt;br /&gt;
                          ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption    (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej13b: &amp;quot;⟦p; q⟧ ⟹ p ∧ q&amp;quot;&lt;br /&gt;
  apply (rule conjI)   (* ⟦p; q⟧ ⟹ p &lt;br /&gt;
                          ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption+   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej13c: &amp;quot;⟦p; q⟧ ⟹ p ∧ q&amp;quot;&lt;br /&gt;
  apply (rule conjI, assumption+)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej13d: &amp;quot;⟦p; q⟧ ⟹ p ∧ q&amp;quot;&lt;br /&gt;
  by (rule conjI, assumption+)&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 14. Demostrar&lt;br /&gt;
     p ∧ q ⊢ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej14a: &amp;quot;p ∧ q ⟹ p&amp;quot;&lt;br /&gt;
  apply (erule conjunct1)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej14b: &amp;quot;p ∧ q ⟹ p&amp;quot;&lt;br /&gt;
  by (erule conjunct1)&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 15. Demostrar&lt;br /&gt;
     p ∧ q ⊢ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej15a: &amp;quot;p ∧ q ⟹ q&amp;quot;&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej15b: &amp;quot;p ∧ q ⟹ q&amp;quot;&lt;br /&gt;
  by (erule conjunct2)&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 16. Demostrar&lt;br /&gt;
     p ∧ (q ∧ r) ⊢ (p ∧ q) ∧ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej16a: &amp;quot;p ∧ (q ∧ r) ⟹ (p ∧ q) ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* p ∧ (q ∧ r) ⟹ p ∧ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
   apply (rule conjI)         (* p ∧ (q ∧ r) ⟹ p&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
    apply (erule conjunct1)   (* p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
   apply (drule conjunct2)    (* q ∧ r ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
   apply (erule conjunct1)    (* p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
  apply (drule conjunct2)     (* q ∧ r ⟹ r *)&lt;br /&gt;
  apply (erule conjunct2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej16b: &amp;quot;p ∧ (q ∧ r) ⟹ (p ∧ q) ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)+         (* p ∧ (q ∧ r) ⟹ p&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
    apply (erule conjE)       (* ⟦p; q ∧ r⟧ ⟹ p&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
  apply assumption            (* p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
   apply (erule conjE)+       (* ⟦p; q; r⟧ ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
  apply assumption            (* p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
  apply (erule conjE)+        (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption            (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej16c: &amp;quot;p ∧ (q ∧ r) ⟹ (p ∧ q) ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)+         (* p ∧ (q ∧ r) ⟹ p&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
    apply (erule conjE,&lt;br /&gt;
           assumption)        (* p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
   apply ((erule conjE)+, &lt;br /&gt;
          assumption)         (* p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
  apply ((erule conjE)+,&lt;br /&gt;
         assumption)          (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej16d: &amp;quot;p ∧ (q ∧ r) ⟹ (p ∧ q) ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)+         (* p ∧ (q ∧ r) ⟹ p&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ q&lt;br /&gt;
                                 p ∧ (q ∧ r) ⟹ r *)&lt;br /&gt;
    apply ((erule conjE)+,&lt;br /&gt;
           assumption)+       (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 17. Demostrar&lt;br /&gt;
     (p ∧ q) ∧ r ⊢ p ∧ (q ∧ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej17a: &amp;quot;(p ∧ q) ∧ r ⟹ p ∧ (q ∧ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)        (* (p ∧ q) ∧ r ⟹ p&lt;br /&gt;
                               (p ∧ q) ∧ r ⟹ q ∧ r *)&lt;br /&gt;
   apply (drule conjunct1)  (* p ∧ q ⟹ p&lt;br /&gt;
                               (p ∧ q) ∧ r ⟹ q ∧ r *)&lt;br /&gt;
   apply (erule conjunct1)  (* (p ∧ q) ∧ r ⟹ q ∧ r *)&lt;br /&gt;
  apply (rule conjI)        (* (p ∧ q) ∧ r ⟹ q&lt;br /&gt;
                               (p ∧ q) ∧ r ⟹ r *)&lt;br /&gt;
   apply (drule conjunct1)  (* p ∧ q ⟹ q&lt;br /&gt;
                               (p ∧ q) ∧ r ⟹ r *)&lt;br /&gt;
   apply (erule conjunct2)  (* (p ∧ q) ∧ r ⟹ r *)&lt;br /&gt;
  apply (erule conjunct2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej17b: &amp;quot;(p ∧ q) ∧ r ⟹ p ∧ (q ∧ r)&amp;quot;&lt;br /&gt;
  apply (erule conjE)   (* ⟦p ∧ q; r⟧ ⟹ p ∧ (q ∧ r) *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦r; p; q⟧ ⟹ p ∧ (q ∧ r) *) &lt;br /&gt;
  apply (erule conjI)   (* ⟦r; q⟧ ⟹ q ∧ r *)&lt;br /&gt;
  apply (erule conjI)   (* r ⟹ r *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej17c: &amp;quot;(p ∧ q) ∧ r ⟹ p ∧ (q ∧ r)&amp;quot;&lt;br /&gt;
  apply (erule conjE)+  (* ⟦r; p; q⟧ ⟹ p ∧ (q ∧ r) *) &lt;br /&gt;
  apply (erule conjI)+  (* r ⟹ r *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 18. Demostrar&lt;br /&gt;
     p ∧ q ⊢ p ⟶ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej18: &amp;quot;p ∧ q ⟹ p ⟶ q&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ∧ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule conjunct2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 19. Demostrar&lt;br /&gt;
     (p ⟶ q) ∧ (p ⟶ r) ⊢ p ⟶ q ∧ r   &lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej19a: &amp;quot;(p ⟶ q) ∧ (p ⟶ r) ⟹ p ⟶ q ∧ r&amp;quot;&lt;br /&gt;
  apply (rule impI)          (* ⟦(p ⟶ q) ∧ (p ⟶ r); p⟧ ⟹ q ∧ r *)&lt;br /&gt;
  apply (rule conjI)         (* ⟦(p ⟶ q) ∧ (p ⟶ r); p⟧ ⟹ q&lt;br /&gt;
                                ⟦(p ⟶ q) ∧ (p ⟶ r); p⟧ ⟹ r *)&lt;br /&gt;
   apply (drule conjunct1)   (* ⟦p; p ⟶ q⟧ ⟹ q *)&lt;br /&gt;
   apply (erule mp)          (* p ⟹ p&lt;br /&gt;
                                ⟦(p ⟶ q) ∧ (p ⟶ r); p⟧ ⟹ r *)&lt;br /&gt;
    apply assumption         (* ⟦(p ⟶ q) ∧ (p ⟶ r); p⟧ ⟹ r *) &lt;br /&gt;
  apply (drule conjunct2)    (* ⟦p; p ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)           (* p ⟹ p *)&lt;br /&gt;
   apply assumption          (* *) &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej19b: &amp;quot;(p ⟶ q) ∧ (p ⟶ r) ⟹ p ⟶ q ∧ r&amp;quot;&lt;br /&gt;
  apply (erule conjE)  (* ⟦p ⟶ q; p ⟶ r⟧ ⟹ p ⟶ q ∧ r *)&lt;br /&gt;
  apply (rule impI)    (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ q ∧ r *)&lt;br /&gt;
  apply (rule conjI)   (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ q&lt;br /&gt;
                          ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
   apply (erule mp)    (* ⟦p ⟶ r; p⟧ ⟹ p&lt;br /&gt;
                          ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
   apply assumption    (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)     (* ⟦p ⟶ q; p⟧ ⟹ p *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej19c: &amp;quot;(p ⟶ q) ∧ (p ⟶ r) ⟹ p ⟶ q ∧ r&amp;quot;&lt;br /&gt;
  apply (erule conjE)  (* ⟦p ⟶ q; p ⟶ r⟧ ⟹ p ⟶ q ∧ r *)&lt;br /&gt;
  apply (rule impI)    (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ q ∧ r *)&lt;br /&gt;
  apply (rule conjI)   (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ q&lt;br /&gt;
                          ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp,&lt;br /&gt;
         assumption)   (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp,&lt;br /&gt;
         assumption)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej19d: &amp;quot;(p ⟶ q) ∧ (p ⟶ r) ⟹ p ⟶ q ∧ r&amp;quot;&lt;br /&gt;
  apply (erule conjE)  (* ⟦p ⟶ q; p ⟶ r⟧ ⟹ p ⟶ q ∧ r *)&lt;br /&gt;
  apply (rule impI)    (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ q ∧ r *)&lt;br /&gt;
  apply (rule conjI)   (* ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ q&lt;br /&gt;
                          ⟦p ⟶ q; p ⟶ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp,&lt;br /&gt;
         assumption)+  (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 20. Demostrar&lt;br /&gt;
     p ⟶ q ∧ r ⊢ (p ⟶ q) ∧ (p ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej20a: &amp;quot;p ⟶ q ∧ r ⟹ (p ⟶ q) ∧ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* p ⟶ q ∧ r ⟹ p ⟶ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
   apply (rule impI)          (* ⟦p ⟶ q ∧ r; p⟧ ⟹ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
   apply (drule mp)           (* p ⟹ p&lt;br /&gt;
                                 ⟦p; q ∧ r⟧ ⟹ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
    apply assumption          (* ⟦p; q ∧ r⟧ ⟹ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
    apply (erule conjunct1)   (* p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)           (* ⟦p ⟶ q ∧ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)            (* p ⟹ p&lt;br /&gt;
                                 ⟦p; q ∧ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption           (* ⟦p; q ∧ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjunct2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej20b: &amp;quot;p ⟶ q ∧ r ⟹ (p ⟶ q) ∧ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* p ⟶ q ∧ r ⟹ p ⟶ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
   apply (rule impI)          (* ⟦p ⟶ q ∧ r; p⟧ ⟹ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption)          (* ⟦p; q ∧ r⟧ ⟹ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
    apply (erule conjunct1)   (* p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)           (* ⟦p ⟶ q ∧ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption)          (* ⟦p; q ∧ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjunct2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej20c: &amp;quot;p ⟶ q ∧ r ⟹ (p ⟶ q) ∧ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* p ⟶ q ∧ r ⟹ p ⟶ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
   apply (rule impI)          (* ⟦p ⟶ q ∧ r; p⟧ ⟹ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjunct1)     (* p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI)           (* ⟦p ⟶ q ∧ r; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjunct2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej20d: &amp;quot;p ⟶ q ∧ r ⟹ (p ⟶ q) ∧ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* p ⟶ q ∧ r ⟹ p ⟶ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI,&lt;br /&gt;
         drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjunct1)     (* p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI,&lt;br /&gt;
         drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjunct2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej20e: &amp;quot;p ⟶ q ∧ r ⟹ (p ⟶ q) ∧ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)    (* p ⟶ q ∧ r ⟹ p ⟶ q&lt;br /&gt;
                           p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI,&lt;br /&gt;
         drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjE)   (* ⟦p; q; r⟧ ⟹ q&lt;br /&gt;
                           p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
   apply assumption     (* p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
   apply (rule impI,&lt;br /&gt;
         drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjE)   (* ⟦p; q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej20f: &amp;quot;p ⟶ q ∧ r ⟹ (p ⟶ q) ∧ (p ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* p ⟶ q ∧ r ⟹ p ⟶ q&lt;br /&gt;
                                 p ⟶ q ∧ r ⟹ p ⟶ r *)&lt;br /&gt;
  apply (rule impI,&lt;br /&gt;
         drule mp,&lt;br /&gt;
         assumption,&lt;br /&gt;
         erule conjE,&lt;br /&gt;
         assumption)+         (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 21. Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r) ⊢ p ∧ q ⟶ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej21a: &amp;quot;p ⟶ (q ⟶ r) ⟹ p ∧ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ⟶ (q ⟶ r); p ∧ q⟧ ⟹ r *)&lt;br /&gt;
  apply (frule conjunct1)   (* ⟦p ⟶ (q ⟶ r); p ∧ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)          (* ⟦p ∧ q; p⟧ ⟹ p&lt;br /&gt;
                               ⟦p ∧ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption         (* ⟦p ∧ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (drule conjunct2)   (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)          (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption         (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej21b: &amp;quot;p ⟶ (q ⟶ r) ⟹ p ∧ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ⟶ (q ⟶ r); p ∧ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjE)       (* ⟦p ⟶ (q ⟶ r); p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)          (* ⟦p; q⟧ ⟹ p&lt;br /&gt;
                               ⟦p; q; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption         (* ⟦p; q; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)          (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption         (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej21c: &amp;quot;p ⟶ (q ⟶ r) ⟹ p ∧ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ⟶ (q ⟶ r); p ∧ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjE)       (* ⟦p ⟶ (q ⟶ r); p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption)        (* ⟦p; q; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp,&lt;br /&gt;
         assumption)        (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej21d: &amp;quot;p ⟶ (q ⟶ r) ⟹ p ∧ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ⟶ (q ⟶ r); p ∧ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjE)       (* ⟦p ⟶ (q ⟶ r); p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption+)+      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 22. Demostrar&lt;br /&gt;
     p ∧ q ⟶ r ⊢ p ⟶ (q ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej22a: &amp;quot;p ∧ q ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)      (* ⟦p ∧ q ⟶ r; p⟧ ⟹ q ⟶ r *)&lt;br /&gt;
  apply (rule impI)      (* ⟦p ∧ q ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)       (* ⟦p; q⟧ ⟹ p ∧ q *)&lt;br /&gt;
  apply (rule conjI)     (* ⟦p; q⟧ ⟹ p&lt;br /&gt;
                            ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption     (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej22b: &amp;quot;p ∧ q ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+     (* ⟦p ∧ q ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)       (* ⟦p; q⟧ ⟹ p ∧ q *)&lt;br /&gt;
  apply (erule conjI)    (* q ⟹ q *)&lt;br /&gt;
  apply assumption       (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej22c: &amp;quot;p ∧ q ⟶ r ⟹ p ⟶ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule impI)+     (* ⟦p ∧ q ⟶ r; p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)       (* ⟦p; q⟧ ⟹ p ∧ q *)&lt;br /&gt;
  apply (erule conjI,&lt;br /&gt;
         assumption)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 23. Demostrar&lt;br /&gt;
     (p ⟶ q) ⟶ r ⊢ p ∧ q ⟶ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej23a: &amp;quot;(p ⟶ q) ⟶ r ⟹ p ∧ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦(p ⟶ q) ⟶ r; p ∧ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)          (* p ∧ q ⟹ p ⟶ q *)&lt;br /&gt;
  apply (rule impI)         (* ⟦p ∧ q; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule conjunct2)   (*  *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 24. Demostrar&lt;br /&gt;
     p ∧ (q ⟶ r) ⊢ (p ⟶ q) ⟶ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej24a: &amp;quot;p ∧ (q ⟶ r) ⟹ (p ⟶ q) ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ∧ (q ⟶ r); p ⟶ q⟧ ⟹ r *)&lt;br /&gt;
  apply (frule conjunct1)   (* ⟦p ∧ (q ⟶ r); p ⟶ q; p⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)          (* ⟦p ∧ (q ⟶ r); p⟧ ⟹ p&lt;br /&gt;
                               ⟦p ∧ (q ⟶ r); p; q⟧ ⟹ r *)&lt;br /&gt;
   apply assumption         (* ⟦p ∧ (q ⟶ r); p; q⟧ ⟹ r *)&lt;br /&gt;
  apply (drule conjunct2)   (* p; q; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)          (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption          (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej24b: &amp;quot;p ∧ (q ⟶ r) ⟹ (p ⟶ q) ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ∧ (q ⟶ r); p ⟶ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjE)       (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp)          (* ⟦p; q ⟶ r⟧ ⟹ p&lt;br /&gt;
                               ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply assumption         (* ⟦p; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)          (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption          (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej24c: &amp;quot;p ∧ (q ⟶ r) ⟹ (p ⟶ q) ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)         (* ⟦p ∧ (q ⟶ r); p ⟶ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjE)       (* ⟦p ⟶ q; p; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (drule mp,&lt;br /&gt;
         assumption+)+      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
section {* Disyunciones *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 25. Demostrar&lt;br /&gt;
     p ⊢ p ∨ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej25: &amp;quot;p ⟹ p ∨ q&amp;quot;&lt;br /&gt;
  apply (erule disjI1)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 26. Demostrar&lt;br /&gt;
     q ⊢ p ∨ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej26: &amp;quot;q ⟹ p ∨ q&amp;quot;&lt;br /&gt;
  apply (erule disjI2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 27. Demostrar&lt;br /&gt;
     p ∨ q ⊢ q ∨ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej27: &amp;quot;p ∨ q ⟹ q ∨ p&amp;quot;&lt;br /&gt;
  apply (erule disjE)     (* p ⟹ q ∨ p&lt;br /&gt;
                             q ⟹ q ∨ p *)&lt;br /&gt;
   apply (erule disjI2)   (* q ⟹ q ∨ p *)&lt;br /&gt;
  apply (erule disjI1)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 28. Demostrar&lt;br /&gt;
     q ⟶ r ⊢ p ∨ q ⟶ p ∨ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej28: &amp;quot;q ⟶ r ⟹ p ∨ q ⟶ p ∨ r&amp;quot;&lt;br /&gt;
  apply (rule impI)       (* ⟦q ⟶ r; p ∨ q⟧ ⟹ p ∨ r *)&lt;br /&gt;
  apply (erule disjE)     (* ⟦q ⟶ r; p⟧ ⟹ p ∨ r&lt;br /&gt;
                             ⟦q ⟶ r; q⟧ ⟹ p ∨ r *)&lt;br /&gt;
   apply (erule disjI1)   (* ⟦q ⟶ r; q⟧ ⟹ p ∨ r *)&lt;br /&gt;
  apply (drule mp)        (* q ⟹ q&lt;br /&gt;
                             ⟦q; r⟧ ⟹ p ∨ r *)&lt;br /&gt;
   apply assumption       (* ⟦q; r⟧ ⟹ p ∨ r *)&lt;br /&gt;
  apply (erule disjI2)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 29. Demostrar&lt;br /&gt;
     p ∨ p ⊢ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej29: &amp;quot;p ∨ p ⟹ p&amp;quot;&lt;br /&gt;
  apply (erule disjE)   (* p ⟹ p&lt;br /&gt;
                           p ⟹ p *)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 30. Demostrar&lt;br /&gt;
     p ⊢ p ∨ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej30: &amp;quot;p ⟹ p ∨ p&amp;quot;&lt;br /&gt;
  apply (erule disjI1)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 31. Demostrar&lt;br /&gt;
     p ∨ (q ∨ r) ⊢ (p ∨ q) ∨ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej31a: &amp;quot;p ∨ (q ∨ r) ⟹ (p ∨ q) ∨ r&amp;quot;&lt;br /&gt;
  apply (erule disjE)     (* p ⟹ (p ∨ q) ∨ r&lt;br /&gt;
                             q ∨ r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
   apply (rule disjI1)    (* p ⟹ p ∨ q&lt;br /&gt;
                             q ∨ r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
   apply (erule disjI1)   (* q ∨ r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
  apply (erule disjE)     (* q ⟹ (p ∨ q) ∨ r&lt;br /&gt;
                             r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
   apply (rule disjI1)    (* q ⟹ p ∨ q&lt;br /&gt;
                             r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
   apply (erule disjI2)   (* r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
  apply (erule disjI2)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej31b: &amp;quot;p ∨ (q ∨ r) ⟹ (p ∨ q) ∨ r&amp;quot;&lt;br /&gt;
  apply (erule disjE)     (* p ⟹ (p ∨ q) ∨ r&lt;br /&gt;
                             q ∨ r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
   apply (rule disjI1)    (* p ⟹ p ∨ q&lt;br /&gt;
                             q ∨ r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
   apply (erule disjI1)   (* q ∨ r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
  apply (erule disjE)     (* q ⟹ (p ∨ q) ∨ r&lt;br /&gt;
                             r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
  apply (rule disjI1,&lt;br /&gt;
         erule disjI2)    (* r ⟹ (p ∨ q) ∨ r *)&lt;br /&gt;
  apply (erule disjI2)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 32. Demostrar&lt;br /&gt;
     (p ∨ q) ∨ r ⊢ p ∨ (q ∨ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej32a: &amp;quot;(p ∨ q) ∨ r ⟹ p ∨ (q ∨ r)&amp;quot;&lt;br /&gt;
  apply (erule disjE)      (* p ∨ q ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
   apply (erule disjE)     (* p ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              q ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
    apply (erule disjI1)   (* q ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
   apply (rule disjI2)     (* q ⟹ q ∨ r&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
   apply (erule disjI1)    (* r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
  apply (rule disjI2)      (* r ⟹ q ∨ r *)&lt;br /&gt;
  apply (erule disjI2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej32b: &amp;quot;(p ∨ q) ∨ r ⟹ p ∨ (q ∨ r)&amp;quot;&lt;br /&gt;
  apply (erule disjE)      (* p ∨ q ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
   apply (erule disjE)     (* p ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              q ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
    apply (erule disjI1)   (* q ⟹ p ∨ (q ∨ r)&lt;br /&gt;
                              r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
  apply (rule disjI2,&lt;br /&gt;
         erule disjI1)     (* r ⟹ p ∨ (q ∨ r) *)&lt;br /&gt;
  apply (rule disjI2,&lt;br /&gt;
         erule disjI2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 33. Demostrar&lt;br /&gt;
     p ∧ (q ∨ r) ⊢ (p ∧ q) ∨ (p ∧ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej33a: &amp;quot;p ∧ (q ∨ r) ⟹ (p ∧ q) ∨ (p ∧ r)&amp;quot;&lt;br /&gt;
  apply (erule conjE)    (* ⟦p; q ∨ r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
  apply (erule disjE)    (* ⟦p; q⟧ ⟹ (p ∧ q) ∨ (p ∧ r)&lt;br /&gt;
                            ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
   apply (rule disjI1)   (* ⟦p; q⟧ ⟹ p ∧ q&lt;br /&gt;
                            ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
   apply (rule conjI)    (* ⟦p; q⟧ ⟹ p&lt;br /&gt;
                            ⟦p; q⟧ ⟹ q&lt;br /&gt;
                            ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
    apply assumption     (* ⟦p; q⟧ ⟹ q&lt;br /&gt;
                            ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
   apply assumption      (* ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
  apply (rule disjI2)    (* ⟦p; r⟧ ⟹ p ∧ r *)&lt;br /&gt;
  apply (rule conjI)     (* ⟦p; r⟧ ⟹ p &lt;br /&gt;
                            ⟦p; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption      (* ⟦p; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption       (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej33b: &amp;quot;p ∧ (q ∨ r) ⟹ (p ∧ q) ∨ (p ∧ r)&amp;quot;&lt;br /&gt;
  apply (erule conjE)    (* ⟦p; q ∨ r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
  apply (erule disjE)    (* ⟦p; q⟧ ⟹ (p ∧ q) ∨ (p ∧ r)&lt;br /&gt;
                            ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
   apply (rule disjI1)   (* ⟦p; q⟧ ⟹ p ∧ q&lt;br /&gt;
                            ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
   apply (erule conjI,&lt;br /&gt;
          assumption)    (* ⟦p; r⟧ ⟹ (p ∧ q) ∨ (p ∧ r) *)&lt;br /&gt;
  apply (rule disjI2)    (* ⟦p; r⟧ ⟹ p ∧ r *)&lt;br /&gt;
  apply (erule conjI,&lt;br /&gt;
         assumption)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 34. Demostrar&lt;br /&gt;
     (p ∧ q) ∨ (p ∧ r) ⊢ p ∧ (q ∨ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej34a: &amp;quot;(p ∧ q) ∨ (p ∧ r) ⟹ p ∧ (q ∨ r)&amp;quot;&lt;br /&gt;
  apply (erule disjE)    (* p ∧ q ⟹ p ∧ (q ∨ r)&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
   apply (erule conjE)   (* ⟦p; q⟧ ⟹ p ∧ (q ∨ r)&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
   apply (rule conjI)    (* ⟦p; q⟧ ⟹ p&lt;br /&gt;
                            ⟦p; q⟧ ⟹ q ∨ r&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
    apply assumption     (* ⟦p; q⟧ ⟹ q ∨ r&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
   apply (rule disjI1)   (* ⟦p; q⟧ ⟹ q&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
   apply assumption      (* p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
  apply (erule conjE)    (* ⟦p; r⟧ ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
  apply (rule conjI)     (* ⟦p; r⟧ ⟹ p&lt;br /&gt;
                            ⟦p; r⟧ ⟹ q ∨ r *)&lt;br /&gt;
   apply assumption      (* ⟦p; r⟧ ⟹ q ∨ r *)&lt;br /&gt;
  apply (erule disjI2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej34b: &amp;quot;(p ∧ q) ∨ (p ∧ r) ⟹ p ∧ (q ∨ r)&amp;quot;&lt;br /&gt;
  apply (erule disjE)    (* p ∧ q ⟹ p ∧ (q ∨ r)&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
   apply (erule conjE)   (* ⟦p; q⟧ ⟹ p ∧ (q ∨ r)&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
  apply (rule conjI,&lt;br /&gt;
         assumption)     (* ⟦p; q⟧ ⟹ q ∨ r&lt;br /&gt;
                            p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
  apply (rule disjI1,&lt;br /&gt;
         assumption)     (* p ∧ r ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
  apply (erule conjE)    (* ⟦p; r⟧ ⟹ p ∧ (q ∨ r) *)&lt;br /&gt;
  apply (rule conjI,&lt;br /&gt;
         assumption)     (* ⟦p; r⟧ ⟹ q ∨ r *)&lt;br /&gt;
  apply (erule disjI2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej34c: &amp;quot;(p ∧ q) ∨ (p ∧ r) ⟹ p ∧ (q ∨ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)          (* (p ∧ q) ∨ (p ∧ r) ⟹ p&lt;br /&gt;
                                 (p ∧ q) ∨ (p ∧ r) ⟹ q ∨ r *)&lt;br /&gt;
   apply (erule disjE)        (* p ∧ q ⟹ p&lt;br /&gt;
                                 p ∧ r ⟹ p&lt;br /&gt;
                                 (p ∧ q) ∨ (p ∧ r) ⟹ q ∨ r *)&lt;br /&gt;
    apply (erule conjunct1)   (* p ∧ r ⟹ p&lt;br /&gt;
                                 (p ∧ q) ∨ (p ∧ r) ⟹ q ∨ r *)&lt;br /&gt;
   apply (erule conjunct1)    (* (p ∧ q) ∨ (p ∧ r) ⟹ q ∨ r *)&lt;br /&gt;
  apply (erule disjE)         (* p ∧ q ⟹ q ∨ r&lt;br /&gt;
                                 p ∧ r ⟹ q ∨ r *)&lt;br /&gt;
   apply (drule conjunct2)    (* q ⟹ q ∨ r&lt;br /&gt;
                                 p ∧ r ⟹ q ∨ r *)&lt;br /&gt;
   apply (rule disjI1)        (* q ⟹ q&lt;br /&gt;
                                 p ∧ r ⟹ q ∨ r *)&lt;br /&gt;
   apply assumption           (* p ∧ r ⟹ q ∨ r *)&lt;br /&gt;
  apply (drule conjunct2)     (* r ⟹ q ∨ r *)&lt;br /&gt;
  apply (erule disjI2)        (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 35. Demostrar&lt;br /&gt;
     p ∨ (q ∧ r) ⊢ (p ∨ q) ∧ (p ∨ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej35a: &amp;quot;p ∨ (q ∧ r) ⟹ (p ∨ q) ∧ (p ∨ r)&amp;quot;&lt;br /&gt;
  apply (erule disjE)      (* p ⟹ (p ∨ q) ∧ (p ∨ r)&lt;br /&gt;
                              q ∧ r ⟹ (p ∨ q) ∧ (p ∨ r) *)&lt;br /&gt;
   apply (rule conjI)      (* p ⟹ p ∨ q&lt;br /&gt;
                              p ⟹ p ∨ r&lt;br /&gt;
                              q ∧ r ⟹ (p ∨ q) ∧ (p ∨ r) *)&lt;br /&gt;
    apply (erule disjI1)   (* p ⟹ p ∨ r&lt;br /&gt;
                              q ∧ r ⟹ (p ∨ q) ∧ (p ∨ r) *)&lt;br /&gt;
   apply (erule disjI1)    (* q ∧ r ⟹ (p ∨ q) ∧ (p ∨ r) *)&lt;br /&gt;
  apply (erule conjE)      (* ⟦q; r⟧ ⟹ (p ∨ q) ∧ (p ∨ r) *)&lt;br /&gt;
  apply (rule conjI)       (* ⟦q; r⟧ ⟹ p ∨ q&lt;br /&gt;
                              ⟦q; r⟧ ⟹ p ∨ r *)&lt;br /&gt;
   apply (erule disjI2)    (* ⟦q; r⟧ ⟹ p ∨ r *)&lt;br /&gt;
  apply (erule disjI2)     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej35b: &amp;quot;p ∨ (q ∧ r) ⟹ (p ∨ q) ∧ (p ∨ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)         (* p ∨ (q ∧ r) ⟹ p ∨ q&lt;br /&gt;
                                p ∨ (q ∧ r) ⟹ p ∨ r *)&lt;br /&gt;
   apply (erule disjE)       (* p ⟹ p ∨ q&lt;br /&gt;
                                q ∧ r ⟹ p ∨ q&lt;br /&gt;
                                p ∨ (q ∧ r) ⟹ p ∨ r *)&lt;br /&gt;
    apply (erule disjI1)     (* q ∧ r ⟹ p ∨ q&lt;br /&gt;
                                p ∨ (q ∧ r) ⟹ p ∨ r *)&lt;br /&gt;
   apply (drule conjunct1)   (* q ⟹ p ∨ q&lt;br /&gt;
                                p ∨ (q ∧ r) ⟹ p ∨ r *)&lt;br /&gt;
   apply (erule disjI2)      (* p ∨ (q ∧ r) ⟹ p ∨ r *)&lt;br /&gt;
  apply (erule disjE)        (* p ⟹ p ∨ r&lt;br /&gt;
                                q ∧ r ⟹ p ∨ r *)&lt;br /&gt;
   apply (erule disjI1)      (* q ∧ r ⟹ p ∨ r *)&lt;br /&gt;
  apply (drule conjunct2)    (* r ⟹ p ∨ r *)&lt;br /&gt;
  apply (erule disjI2)       (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 36. Demostrar&lt;br /&gt;
     (p ∨ q) ∧ (p ∨ r) ⊢ p ∨ (q ∧ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej36a: &amp;quot;(p ∨ q) ∧ (p ∨ r) ⟹ p ∨ (q ∧ r)&amp;quot;&lt;br /&gt;
  apply (erule conjE)     (* ⟦p ∨ q; p ∨ r⟧ ⟹ p ∨ (q ∧ r) *)&lt;br /&gt;
  apply (erule disjE)     (* ⟦p ∨ r; p⟧ ⟹ p ∨ (q ∧ r)&lt;br /&gt;
                             ⟦p ∨ r; q⟧ ⟹ p ∨ (q ∧ r) *)&lt;br /&gt;
   apply (erule disjI1)   (* ⟦p ∨ r; q⟧ ⟹ p ∨ (q ∧ r) *)&lt;br /&gt;
  apply (erule disjE)     (* ⟦q; p⟧ ⟹ p ∨ (q ∧ r)&lt;br /&gt;
                             ⟦q; r⟧ ⟹ p ∨ (q ∧ r) *)&lt;br /&gt;
   apply (erule disjI1)   (* ⟦q; r⟧ ⟹ p ∨ (q ∧ r) *)&lt;br /&gt;
  apply (rule disjI2)     (* ⟦q; r⟧ ⟹ q ∧ r *)&lt;br /&gt;
  apply (rule conjI)      (* ⟦q; r⟧ ⟹ q&lt;br /&gt;
                             ⟦q; r⟧ ⟹ r *)&lt;br /&gt;
   apply assumption       (* ⟦q; r⟧ ⟹ r *)&lt;br /&gt;
  apply assumption        (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 37. Demostrar&lt;br /&gt;
     (p ⟶ r) ∧ (q ⟶ r) ⊢ p ∨ q ⟶ r&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej37a: &amp;quot;(p ⟶ r) ∧ (q ⟶ r) ⟹ p ∨ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)           (* ⟦(p ⟶ r) ∧ (q ⟶ r); p ∨ q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule conjE)         (* ⟦p ∨ q; p ⟶ r; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule disjE)         (* ⟦p ⟶ r; q ⟶ r; p⟧ ⟹ r&lt;br /&gt;
                                 ⟦p ⟶ r; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply (erule mp)           (* ⟦q ⟶ r; p⟧ ⟹ p&lt;br /&gt;
                                 ⟦p ⟶ r; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply assumption           (* ⟦p ⟶ r; q ⟶ r; q⟧ ⟹ r *) &lt;br /&gt;
  apply (erule_tac P=q in mp) (* ⟦p ⟶ r; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption            (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej37b: &amp;quot;(p ⟶ r) ∧ (q ⟶ r) ⟹ p ∨ q ⟶ r&amp;quot;&lt;br /&gt;
  apply (rule impI)       (* (p ⟶ r) ∧ (q ⟶ r) ⟹ p ∨ q ⟹ r *)     &lt;br /&gt;
  apply (erule conjE)     (* ⟦p ∨ q; p ⟶ r; q ⟶ r⟧ ⟹ r *)&lt;br /&gt;
  apply (erule disjE)     (* ⟦p ⟶ r; q ⟶ r; p⟧ ⟹ r&lt;br /&gt;
                             ⟦p ⟶ r; q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
   apply (erule mp,    &lt;br /&gt;
          assumption+)+   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 38. Demostrar&lt;br /&gt;
     p ∨ q ⟶ r ⊢ (p ⟶ r) ∧ (q ⟶ r)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej38a: &amp;quot;p ∨ q ⟶ r ⟹ (p ⟶ r) ∧ (q ⟶ r)&amp;quot;&lt;br /&gt;
  apply (rule conjI)      (* p ∨ q ⟶ r ⟹ p ⟶ r&lt;br /&gt;
                             p ∨ q ⟶ r ⟹ q ⟶ r *)&lt;br /&gt;
   apply (rule impI)      (* ⟦p ∨ q ⟶ r; p⟧ ⟹ r&lt;br /&gt;
                             p ∨ q ⟶ r ⟹ q ⟶ r *)&lt;br /&gt;
   apply (erule mp)       (* p ⟹ p ∨ q&lt;br /&gt;
                             p ∨ q ⟶ r ⟹ q ⟶ r *)&lt;br /&gt;
    apply (erule disjI1)  (* p ∨ q ⟶ r ⟹ q ⟶ r *)&lt;br /&gt;
  apply (rule impI)       (* ⟦p ∨ q ⟶ r; q⟧ ⟹ r *)&lt;br /&gt;
  apply (erule mp)        (* q ⟹ p ∨ q *)&lt;br /&gt;
  apply (erule disjI2)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
section {* Negación *}&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 39. Demostrar&lt;br /&gt;
     p ⊢ ¬¬p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej39: &amp;quot;p ⟹ ¬¬p&amp;quot;&lt;br /&gt;
  apply (rule notI)    (* ⟦p; ¬ p⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)   (* p ⟹ p *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 40. Demostrar&lt;br /&gt;
     ¬p ⊢ p ⟶ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej40: &amp;quot;¬p ⟹ p ⟶ q&amp;quot;&lt;br /&gt;
  apply (rule impI)   (* ⟦¬ p; p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule notE)  (* p ⟹ p *)&lt;br /&gt;
  apply assumption    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 41. Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬q ⟶ ¬p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej41: &amp;quot;p ⟶ q ⟹ ¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
  apply (rule impI)    (* ⟦p ⟶ q; ¬ q⟧ ⟹ ¬ p *)  &lt;br /&gt;
  apply (rule notI)    (* ⟦p ⟶ q; ¬ q; p⟧ ⟹ False *)&lt;br /&gt;
  apply (drule mp)     (* ⟦¬ q; p⟧ ⟹ p&lt;br /&gt;
                          ⟦¬ q; p; q⟧ ⟹ False *)&lt;br /&gt;
   apply assumption    (* ⟦¬ q; p; q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)   (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 42. Demostrar&lt;br /&gt;
     p ∨ q, ¬q ⊢ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej42: &amp;quot;⟦p ∨ q; ¬q⟧ ⟹ p&amp;quot;&lt;br /&gt;
  apply (erule disjE)   (* ⟦¬ q; p⟧ ⟹ p&lt;br /&gt;
                           ⟦¬ q; q⟧ ⟹ p *)&lt;br /&gt;
   apply assumption     (* ⟦¬ q; q⟧ ⟹ p  *)&lt;br /&gt;
  apply (erule notE)    (* q ⟹ q *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 43. Demostrar&lt;br /&gt;
     p ∨ q, ¬p ⊢ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej43: &amp;quot;⟦p ∨ q; ¬p⟧ ⟹ q&amp;quot;&lt;br /&gt;
  apply (erule disjE)   (* ⟦¬ p; p⟧ ⟹ q&lt;br /&gt;
                           ⟦¬ p; q⟧ ⟹ q *)&lt;br /&gt;
   apply (erule notE)   (* p ⟹ p&lt;br /&gt;
                           ⟦¬ p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption     (* ⟦¬ p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption      (* ⟦¬ p; q⟧ ⟹ q *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 44. Demostrar&lt;br /&gt;
     p ∨ q ⊢ ¬(¬p ∧ ¬q)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej44a: &amp;quot;p ∨ q ⟹ ¬(¬p ∧ ¬q)&amp;quot;&lt;br /&gt;
  apply (rule notI)              (* ⟦p ∨ q; ¬ p ∧ ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)            (* ⟦p ∨ q; ¬ p; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule disjE)            (* ⟦¬ p; ¬ q; p⟧ ⟹ False&lt;br /&gt;
                                    ⟦¬ p; ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
   apply (erule notE)            (* ⟦¬ q; p⟧ ⟹ p&lt;br /&gt;
                                    ⟦¬ p; ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
   apply assumption              (* ⟦¬ p; ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule_tac P=q in notE)  (* ⟦¬ p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption               (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej44: &amp;quot;p ∨ q ⟹ ¬(¬p ∧ ¬q)&amp;quot;&lt;br /&gt;
  apply (rule notI)                (* ⟦p ∨ q; ¬ p ∧ ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)              (* ⟦p ∨ q; ¬ p; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule disjE)              (* ⟦¬ p; ¬ q; p⟧ ⟹ False&lt;br /&gt;
                                      ⟦¬ p; ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
   apply (erule notE, assumption)+ (* *)&lt;br /&gt;
  done                            &lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 45. Demostrar&lt;br /&gt;
     p ∧ q ⊢ ¬(¬p ∨ ¬q)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej45a: &amp;quot;p ∧ q ⟹ ¬(¬p ∨ ¬q)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* ⟦p ∧ q; ¬ p ∨ ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦¬ p ∨ ¬ q; p; q⟧ ⟹ False *) &lt;br /&gt;
  apply (erule disjE)   (* ⟦p; q; ¬ p⟧ ⟹ False&lt;br /&gt;
                           ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
   apply (erule notE)   (* ⟦p; q⟧ ⟹ p&lt;br /&gt;
                           ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
   apply assumption     (* ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)    (* ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej45b: &amp;quot;p ∧ q ⟹ ¬(¬p ∨ ¬q)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* ⟦p ∧ q; ¬ p ∨ ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦¬ p ∨ ¬ q; p; q⟧ ⟹ False *) &lt;br /&gt;
  apply (erule disjE)   (* ⟦p; q; ¬ p⟧ ⟹ False&lt;br /&gt;
                           ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE,&lt;br /&gt;
         assumption)    (* ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE,&lt;br /&gt;
         assumption)    (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej45c: &amp;quot;p ∧ q ⟹ ¬(¬p ∨ ¬q)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* ⟦p ∧ q; ¬ p ∨ ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦¬ p ∨ ¬ q; p; q⟧ ⟹ False *) &lt;br /&gt;
  apply (erule disjE)   (* ⟦p; q; ¬ p⟧ ⟹ False&lt;br /&gt;
                           ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE,&lt;br /&gt;
         assumption)+   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 46. Demostrar&lt;br /&gt;
     ¬(p ∨ q) ⊢ ¬p ∧ ¬q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej46b: &amp;quot;¬(p ∨ q) ⟹ ¬p ∧ ¬q&amp;quot;&lt;br /&gt;
  apply (rule conjI)     (* ¬ (p ∨ q) ⟹ ¬ p&lt;br /&gt;
                            ¬ (p ∨ q) ⟹ ¬ q *)&lt;br /&gt;
   apply (rule notI)     (* ⟦¬ (p ∨ q); p⟧ ⟹ False&lt;br /&gt;
                            ¬ (p ∨ q) ⟹ ¬ q *)&lt;br /&gt;
   apply (erule notE)    (* p ⟹ p ∨ q&lt;br /&gt;
                            ¬ (p ∨ q) ⟹ ¬ q *)&lt;br /&gt;
   apply (erule disjI1)  (* ¬ (p ∨ q) ⟹ ¬ q *)&lt;br /&gt;
  apply (rule notI)      (* ⟦¬ (p ∨ q); q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)     (* q ⟹ p ∨ q *)&lt;br /&gt;
  apply (erule disjI2)   (* *) &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej46b: &amp;quot;¬(p ∨ q) ⟹ ¬p ∧ ¬q&amp;quot;&lt;br /&gt;
  apply (rule conjI)       (* ¬ (p ∨ q) ⟹ ¬ p&lt;br /&gt;
                              ¬ (p ∨ q) ⟹ ¬ q *)&lt;br /&gt;
  apply (rule notI,&lt;br /&gt;
         erule notE,&lt;br /&gt;
         (erule disjI1 |&lt;br /&gt;
          erule disjI2))+  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej46c: &amp;quot;¬(p ∨ q) ⟹ ¬p ∧ ¬q&amp;quot;&lt;br /&gt;
  by (rule conjI,&lt;br /&gt;
      (rule notI,&lt;br /&gt;
       erule notE,&lt;br /&gt;
       (erule disjI1 |&lt;br /&gt;
        erule disjI2))+)&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 47. Demostrar&lt;br /&gt;
     ¬p ∧ ¬q ⊢ ¬(p ∨ q)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej47a: &amp;quot;¬p ∧ ¬q ⟹ ¬(p ∨ q)&amp;quot;&lt;br /&gt;
  apply (rule notI)              (* ⟦¬ p ∧ ¬ q; p ∨ q⟧ ⟹ False *) &lt;br /&gt;
  apply (erule disjE)            (* ⟦¬ p ∧ ¬ q; p⟧ ⟹ False&lt;br /&gt;
                                    ⟦¬ p ∧ ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
   apply (drule conjunct1)       (* ⟦p; ¬ p⟧ ⟹ False&lt;br /&gt;
                                    ⟦¬ p ∧ ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
   apply (erule notE)            (* p ⟹ p&lt;br /&gt;
                                    ⟦¬ p ∧ ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
   apply assumption              (* ⟦¬ p ∧ ¬ q; q⟧ ⟹ False*)&lt;br /&gt;
  apply (drule conjunct2)        (* ⟦q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)             (* q ⟹ q *)&lt;br /&gt;
  apply assumption               (* *)&lt;br /&gt;
&lt;br /&gt;
lemma ej47b: &amp;quot;¬p ∧ ¬q ⟹ ¬(p ∨ q)&amp;quot;&lt;br /&gt;
  apply (rule notI)              (* ⟦¬ p ∧ ¬ q; p ∨ q⟧ ⟹ False *) &lt;br /&gt;
  apply (erule disjE)            (* ⟦¬ p ∧ ¬ q; p⟧ ⟹ False&lt;br /&gt;
                                    ⟦¬ p ∧ ¬ q; q⟧ ⟹ False *)&lt;br /&gt;
  apply ((drule conjunct1 |&lt;br /&gt;
          drule conjunct2),&lt;br /&gt;
         erule notE,&lt;br /&gt;
         assumption)+            (* *)&lt;br /&gt;
&lt;br /&gt;
lemma ej47: &amp;quot;¬p ∧ ¬q ⟹ ¬(p ∨ q)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* ⟦¬ p ∧ ¬ q; p ∨ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦p ∨ q; ¬ p; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE, &lt;br /&gt;
          assumption)+  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 48. Demostrar&lt;br /&gt;
     ¬p ∨ ¬q ⊢ ¬(p ∧ q)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej48a: &amp;quot;¬p ∨ ¬q ⟹ ¬(p ∧ q)&amp;quot;&lt;br /&gt;
  apply (rule notI)         (* ⟦¬ p ∨ ¬ q; p ∧ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule disjE)       (* ⟦p ∧ q; ¬ p⟧ ⟹ False&lt;br /&gt;
                               ⟦p ∧ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
   apply (drule conjunct1)  (* ⟦¬ p; p⟧ ⟹ False&lt;br /&gt;
                               ⟦p ∧ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
   apply (erule notE)       (* p ⟹ p&lt;br /&gt;
                               ⟦p ∧ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
   apply assumption         (* ⟦p ∧ q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (drule conjunct2)   (* ⟦¬ q; q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)        (* q ⟹ q *)&lt;br /&gt;
  apply assumption          (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej48b: &amp;quot;¬p ∨ ¬q ⟹ ¬(p ∧ q)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* ⟦¬ p ∨ ¬ q; p ∧ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦¬ p ∨ ¬ q; p; q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule disjE)   (* ⟦p; q; ¬ p⟧ ⟹ False&lt;br /&gt;
                           ⟦p; q; ¬ q⟧ ⟹ False *)&lt;br /&gt;
   apply (erule notE, &lt;br /&gt;
          assumption)+  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 49. Demostrar&lt;br /&gt;
     ⊢ ¬(p ∧ ¬p)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej49: &amp;quot;¬(p ∧ ¬p)&amp;quot;&lt;br /&gt;
  apply (rule notI)     (* p ∧ ¬ p ⟹ False *)&lt;br /&gt;
  apply (erule conjE)   (* ⟦p; ¬ p⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)    (* ⟦p; ¬ p⟧ ⟹ False *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 50. Demostrar&lt;br /&gt;
     p ∧ ¬p ⊢ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej50: &amp;quot;p ∧ ¬p ⟹ q&amp;quot;&lt;br /&gt;
  apply (erule conjE)  (* ⟦p; ¬ p⟧ ⟹ q *)&lt;br /&gt;
  apply (erule notE)   (* p ⟹ p *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 51. Demostrar&lt;br /&gt;
     ¬¬p ⊢ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej51: &amp;quot;¬¬p ⟹ p&amp;quot;&lt;br /&gt;
  apply (erule notnotD)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 52. Demostrar&lt;br /&gt;
     ⊢ p ∨ ¬p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej52: &amp;quot;p ∨ ¬p&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;¬p&amp;quot; in excluded_middle) (* ¬¬p ∨ ¬p ⟹ p ∨ ¬p*)&lt;br /&gt;
  apply (erule disjE)                       (* ¬ ¬ p ⟹ p ∨ ¬ p&lt;br /&gt;
                                               ¬ p ⟹ p ∨ ¬ p *) &lt;br /&gt;
  apply (rule disjI1)                       (* ¬ ¬ p ⟹ p&lt;br /&gt;
                                               ¬ p ⟹ p ∨ ¬ p *)&lt;br /&gt;
   apply (erule notnotD)                    (* ¬ p ⟹ p ∨ ¬ p *) &lt;br /&gt;
  apply (erule disjI2)                      (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 53. Demostrar&lt;br /&gt;
     ⊢ ((p ⟶ q) ⟶ p) ⟶ p&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej53: &amp;quot;((p ⟶ q) ⟶ p) ⟶ p&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;p ⟶ q&amp;quot; in excluded_middle)&lt;br /&gt;
                       (* ¬ (p ⟶ q) ∨ (p ⟶ q) ⟹&lt;br /&gt;
                          ((p ⟶ q) ⟶ p) ⟶ p *)&lt;br /&gt;
  apply (erule disjE)  (* ¬ (p ⟶ q) ⟹ ((p ⟶ q) ⟶ p) ⟶ p&lt;br /&gt;
                          p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *)&lt;br /&gt;
   apply (rule impI)   (* ⟦¬ (p ⟶ q); (p ⟶ q) ⟶ p⟧ ⟹ p&lt;br /&gt;
                          p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *)&lt;br /&gt;
  apply (rule ccontr)  (* ⟦¬ (p ⟶ q); (p ⟶ q) ⟶ p; ¬ p⟧ ⟹ False&lt;br /&gt;
                          p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *)&lt;br /&gt;
   apply (erule_tac P=&amp;quot;p ⟶ q&amp;quot; in notE)&lt;br /&gt;
                       (* ⟦(p ⟶ q) ⟶ p; ¬ p⟧ ⟹ p ⟶ q&lt;br /&gt;
                          p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *) &lt;br /&gt;
   apply (rule impI)   (* ⟦(p ⟶ q) ⟶ p; ¬ p; p⟧ ⟹ q&lt;br /&gt;
                          p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *)&lt;br /&gt;
   apply (erule notE)  (* ⟦(p ⟶ q) ⟶ p; p⟧ ⟹ p&lt;br /&gt;
                          p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *) &lt;br /&gt;
   apply assumption    (* p ⟶ q ⟹ ((p ⟶ q) ⟶ p) ⟶ p *)&lt;br /&gt;
  apply (rule impI)    (* ⟦p ⟶ q; (p ⟶ q) ⟶ p⟧ ⟹ p *)&lt;br /&gt;
  apply (erule_tac P=&amp;quot;p ⟶q&amp;quot; in mp)&lt;br /&gt;
                       (*  p ⟶ q ⟹ p ⟶ q *)&lt;br /&gt;
  apply assumption     (* *)&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 54. Demostrar&lt;br /&gt;
     ¬q ⟶ ¬p ⊢ p ⟶ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej54: &amp;quot;¬q ⟶ ¬p ⟹ p ⟶ q&amp;quot;&lt;br /&gt;
  apply (rule impI)      (* ⟦¬ q ⟶ ¬ p; p⟧ ⟹ q *)&lt;br /&gt;
  apply (rule notnotD)   (* ⟦¬ q ⟶ ¬ p; p⟧ ⟹ ¬ ¬ q *)&lt;br /&gt;
  apply (erule mt)       (* p ⟹ ¬ ¬ p *)&lt;br /&gt;
  apply (erule notnotI)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 55. Demostrar&lt;br /&gt;
     ¬(¬p ∧ ¬q) ⊢ p ∨ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej55: &amp;quot;¬(¬p ∧ ¬q) ⟹ p ∨ q&amp;quot;&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
                        (* ⟦¬ (¬ p ∧ ¬ q); ¬ p ∨ p⟧ ⟹ p ∨ q *)  &lt;br /&gt;
  apply (erule disjE)   (* ⟦¬ (¬ p ∧ ¬ q); ¬ p⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
   apply (cut_tac P=q in excluded_middle)&lt;br /&gt;
                        (* ⟦¬ (¬ p ∧ ¬ q); ¬ p; ¬ q ∨ q⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
   apply (erule disjE)  (* ⟦¬ (¬ p ∧ ¬ q); ¬ p; ¬ q⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); ¬ p; q⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
    apply (erule notE)  (* ⟦¬ p; ¬ q⟧ ⟹ ¬ p ∧ ¬ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); ¬ p; q⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
    apply (rule conjI)  (* ⟦¬ p; ¬ q⟧ ⟹ ¬ p&lt;br /&gt;
                           ⟦¬ p; ¬ q⟧ ⟹ ¬ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); ¬ p; q⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
     apply assumption+  (* ⟦¬ (¬ p ∧ ¬ q); ¬ p; q⟧ ⟹ p ∨ q&lt;br /&gt;
                           ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
   apply (erule disjI2) (* ⟦¬ (¬ p ∧ ¬ q); p⟧ ⟹ p ∨ q *)&lt;br /&gt;
  apply (erule disjI1)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 56. Demostrar&lt;br /&gt;
     ¬(¬p ∨ ¬q) ⊢ p ∧ q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej56a: &amp;quot;¬(¬p ∨ ¬q) ⟹ p ∧ q&amp;quot;&lt;br /&gt;
  apply (rule conjI)     (* ¬ (¬ p ∨ ¬ q) ⟹ p&lt;br /&gt;
                            ¬ (¬ p ∨ ¬ q) ⟹ q *)&lt;br /&gt;
   apply (rule ccontr)   (* ⟦¬ (¬ p ∨ ¬ q); ¬ p⟧ ⟹ False&lt;br /&gt;
                            ¬ (¬ p ∨ ¬ q) ⟹ q *)&lt;br /&gt;
   apply (erule notE)    (* ¬ p ⟹ ¬ p ∨ ¬ q&lt;br /&gt;
                            ¬ (¬ p ∨ ¬ q) ⟹ q *)&lt;br /&gt;
   apply (erule disjI1)  (* ¬ (¬ p ∨ ¬ q) ⟹ q *)&lt;br /&gt;
  apply (rule ccontr)    (* ⟦¬ (¬ p ∨ ¬ q); ¬ q⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)     (* ¬ q ⟹ ¬ p ∨ ¬ q *)&lt;br /&gt;
  apply (erule disjI2)   (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 57. Demostrar&lt;br /&gt;
     ¬(p ∧ q) ⊢ ¬p ∨ ¬q&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej57: &amp;quot;¬(p ∧ q) ⟹ ¬p ∨ ¬q&amp;quot;&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
                         (* ⟦¬ (p ∧ q); ¬ p ∨ p⟧ ⟹ ¬ p ∨ ¬ q *)&lt;br /&gt;
  apply (erule disjE)    (* ⟦¬ (p ∧ q); ¬ p⟧ ⟹ ¬ p ∨ ¬ q&lt;br /&gt;
                            ⟦¬ (p ∧ q); p⟧ ⟹ ¬ p ∨ ¬ q *)&lt;br /&gt;
   apply (erule disjI1)  (* ⟦¬ (p ∧ q); p⟧ ⟹ ¬ p ∨ ¬ q *)&lt;br /&gt;
  apply (cut_tac P=q in excluded_middle)&lt;br /&gt;
                         (* ⟦¬ (p ∧ q); p; ¬ q ∨ q⟧ ⟹ ¬ p ∨ ¬ q *)&lt;br /&gt;
  apply (erule disjE)    (* ⟦¬ (p ∧ q); p; ¬ q⟧ ⟹ ¬ p ∨ ¬ q&lt;br /&gt;
                            ⟦¬ (p ∧ q); p; q⟧ ⟹ ¬ p ∨ ¬ q *)&lt;br /&gt;
   apply (erule disjI2)  (* ⟦¬ (p ∧ q); p; q⟧ ⟹ ¬ p ∨ ¬ q *) &lt;br /&gt;
  apply (erule notE)     (* ⟦p; q⟧ ⟹ p ∧ q *)&lt;br /&gt;
  apply (rule conjI)     (* ⟦p; q⟧ ⟹ p&lt;br /&gt;
                            ⟦p; q⟧ ⟹ q *)&lt;br /&gt;
   apply assumption+     (* *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* --------------------------------------------------------------- &lt;br /&gt;
  Ejercicio 58. Demostrar&lt;br /&gt;
     ⊢ (p ⟶ q) ∨ (q ⟶ p)&lt;br /&gt;
  ------------------------------------------------------------------ *}&lt;br /&gt;
&lt;br /&gt;
lemma ej58a: &amp;quot;(p ⟶ q) ∨ (q ⟶ p)&amp;quot;&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
                        (* ¬ p ∨ p ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (erule disjE)   (* ¬ p ⟹ (p ⟶ q) ∨ (q ⟶ p)&lt;br /&gt;
                           p ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply (rule disjI1)  (* ¬ p ⟹ p ⟶ q&lt;br /&gt;
                           p ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (rule impI)     (* ⟦¬ p; p⟧ ⟹ q&lt;br /&gt;
                           p ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (erule notE)    (* p ⟹ p&lt;br /&gt;
                           p ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply assumption     (* p ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (rule disjI2)   (* p ⟹ q ⟶ p *)&lt;br /&gt;
  apply (rule impI)     (* ⟦p; q⟧ ⟹ p *)&lt;br /&gt;
  apply assumption      (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej58b: &amp;quot;(p ⟶ q) ∨ (q ⟶ p)&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;p ⟶ q&amp;quot; in excluded_middle)&lt;br /&gt;
                        (* ¬ (p ⟶ q) ∨ (p ⟶ q) ⟹&lt;br /&gt;
                           (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (erule disjE)   (* ¬ (p ⟶ q) ⟹ (p ⟶ q) ∨ (q ⟶ p)&lt;br /&gt;
                           p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply (rule disjI2)  (* ¬ (p ⟶ q) ⟹ q ⟶ p&lt;br /&gt;
                           p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply (rule impI)    (* ⟦¬ (p ⟶ q); q⟧ ⟹ p&lt;br /&gt;
                           p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (erule notE)    (* q ⟹ p ⟶ q&lt;br /&gt;
                           p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply (rule impI)    (* ⟦q; p⟧ ⟹ q&lt;br /&gt;
                           p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply assumption     (* p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (erule disjI1)  (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej58c: &amp;quot;(p ⟶ q) ∨ (q ⟶ p)&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;¬(p ⟶ q)&amp;quot; in excluded_middle)&lt;br /&gt;
         (* ¬ ¬ (p ⟶ q) ∨ ¬ (p ⟶ q) ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (erule disjE)     (* ¬ ¬ (p ⟶ q) ⟹ (p ⟶ q) ∨ (q ⟶ p)&lt;br /&gt;
                             ¬ (p ⟶ q) ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply (drule notnotD)  (* p ⟶ q ⟹ (p ⟶ q) ∨ (q ⟶ p)&lt;br /&gt;
                             ¬ (p ⟶ q) ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
   apply (erule disjI1)   (* ¬ (p ⟶ q) ⟹ (p ⟶ q) ∨ (q ⟶ p) *)&lt;br /&gt;
  apply (rule disjI2)     (* ¬ (p ⟶ q) ⟹ q ⟶ p *)&lt;br /&gt;
  apply (rule impI)       (* ⟦¬ (p ⟶ q); q⟧ ⟹ p *)&lt;br /&gt;
  apply (erule notE)      (* q ⟹ p ⟶ q *)&lt;br /&gt;
  apply (rule impI)       (* ⟦q; p⟧ ⟹ q *)&lt;br /&gt;
  apply assumption        (* *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Relaci%C3%B3n_3&amp;diff=571</id>
		<title>Relación 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Relaci%C3%B3n_3&amp;diff=571"/>
		<updated>2019-04-11T14:44:16Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=== Relación 3: Deducción natural en lógica proposicional ===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 1.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
: {p → r, r → ¬ q} ⊧ ¬(p ∧ q)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; sofsanfer, luiporpir, paurinara&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej1rel3.png]]&lt;br /&gt;
&lt;br /&gt;
migtromol, nurgomvar, matcarcar, roccorcor&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Ejercicio3.1.PNG]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 2.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
: ¬p ∧ ¬q  ⊧ ¬(p ∨ q)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; sofsanfer, migtromol, luiporpir, nurgomvar, matcarcar, paurinara, roccorcor&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej2rel3.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 3.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
: p ∨ q ⊧ ¬(¬ p ∧ ¬ q )&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; sofsanfer, migtromol, luiporpir, nurgomvar, matcarcar, paurinara, roccorcor &lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej3rel3.png]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 4.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
: ¬ p ∨ ¬ q ⊧ ¬( p ∧ q )&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; sofsanfer, migtromol, luiporpir, nurgomvar, matcarcar, paurinara, roccorcor&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej4rel3.png]]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 5.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
: {p → r, r → ¬ q} ⊧ ¬(p ∧ q)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; sofsanfer, migtromol, luiporpir, nurgomvar, paurinara, roccorcor&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej5rel3.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 6.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
:  ⊧ ((p → q) → p)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; luiporpir, sofsanfer&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej6_rel3.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 7.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
: (p → q) ∨ (q → p)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
josgutde3&lt;br /&gt;
&lt;br /&gt;
Usaremos dos lemas en la demostración:&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Lema 1.&amp;#039;&amp;#039;&amp;#039; ¬(F → G) ⊧ F ∧ ¬G&lt;br /&gt;
: [[Archivo:lema_1.jpg]]&lt;br /&gt;
: &amp;#039;&amp;#039;&amp;#039;Ley de De Morgan.&amp;#039;&amp;#039;&amp;#039; ¬(F ∨ G) ⊧ ¬F ∧ ¬G&lt;br /&gt;
: [[Archivo:lema_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
: Ahora podemos demostrar que ⊧(p → q) ∨ (q → p)&lt;br /&gt;
: [[Archivo:ej7rel3_2.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sofsanfer&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ej7rel3sofsanfer.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Ejercicio 8.&amp;#039;&amp;#039;&amp;#039; Demostrar mediante deducción natural:&lt;br /&gt;
:  p → (q ∧ r) ⊧ (p → q) ∨ (p → r)&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solución:&amp;#039;&amp;#039;&amp;#039; Antmorlop8, luiporpir, nurgomvar, sofsanfer&lt;br /&gt;
&lt;br /&gt;
[[Archivo:ejercicio8.jpg]&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=P%C3%A1gina_principal&amp;diff=567</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=P%C3%A1gina_principal&amp;diff=567"/>
		<updated>2019-04-11T14:41:59Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Este sitio contiene materiales del curso [https://www.cs.us.es/~jalonso/cursos/lmf/temas.php &amp;#039;&amp;#039;&amp;#039;Lógica matemática y fundamentos&amp;#039;&amp;#039;&amp;#039;] de 3º del [http://www.us.es/estudios/grados/plan_171?p=7 Grado en Matemáticas] de la [http://www.us.es Universidad de Sevilla].&lt;br /&gt;
&lt;br /&gt;
== Material para el curso ==&lt;br /&gt;
* [[Temas]]: Transparencias de los temas y teorías.&lt;br /&gt;
* [[Ejercicios]]: Relaciones de ejercicios.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_en_l%C3%B3gica_de_primer_orden_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=529</id>
		<title>Deducción natural en lógica de primer orden con Isabelle/HOL basada en tácticas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_en_l%C3%B3gica_de_primer_orden_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=529"/>
		<updated>2019-04-01T12:27:38Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
theory T4b&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Introducción&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Reglas de primer orden en Isabelle/HOL&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
thm spec [no_vars]&lt;br /&gt;
  (* da ∀x. P x ⟹ P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm allE [no_vars]&lt;br /&gt;
  (* da ⟦∀x. P x; P x ⟹ R⟧ ⟹ R *)  &lt;br /&gt;
  &lt;br /&gt;
thm allI [no_vars]&lt;br /&gt;
  (* da (⋀x. P x) ⟹ ∀x. P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm exI &lt;br /&gt;
  (* da ?P ?x ⟹ ∃x. ?P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm exE [no_vars]&lt;br /&gt;
  (* da ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q *)  &lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Ejemplos de demostraciones&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con spec y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;  &lt;br /&gt;
  apply (drule_tac x=a in spec)  (* da P a ⟹ ∃y. P y *)&lt;br /&gt;
  apply (rule_tac x=a in exI)    (* da P a ⟹ P a *)&lt;br /&gt;
  apply assumption               (* da  No subgoals!*)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Explicaciones:&lt;br /&gt;
 apply (drule_tac x=a in spec)&lt;br /&gt;
 + Objetivo:       &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
 + spec:           &amp;quot;∀x. ?P x ⟹ ?P ?x&amp;quot;&lt;br /&gt;
 + spec &amp;quot;x=a&amp;quot;:     &amp;quot;∀x. ?P x ⟹ ?P a&amp;quot; &lt;br /&gt;
 + Unificador de   &amp;quot;∀x. P x&amp;quot; con &lt;br /&gt;
                   &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
   es              ?P/P&lt;br /&gt;
 + Nuevo objetivo: &amp;quot;P a ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 apply (rule_tac x=a in exI)&lt;br /&gt;
 + Objetivo:       &amp;quot;P a ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
 + exI:            &amp;quot;?P ?x ⟹ ∃x. ?P x&amp;quot;&lt;br /&gt;
 + exI &amp;quot;x=a&amp;quot;:      &amp;quot;?P a ⟹ ∃x. ?P x&amp;quot;&lt;br /&gt;
 + Unificador de   &amp;quot;∃y. P y&amp;quot; con &lt;br /&gt;
                   &amp;quot;∃x. ?P x&amp;quot;&lt;br /&gt;
   es              ?P/P&lt;br /&gt;
 + Nuevo objetivo: &amp;quot;P a ⟹ P a&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con spec y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule exI)    (* da ∀x. P x ⟹ P ?x *)&lt;br /&gt;
  apply (erule spec)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Explicaciones&lt;br /&gt;
 apply (rule exI)&lt;br /&gt;
 + Objetivo:       &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
 + exI:            &amp;quot;?P ?x ⟹ ∃x. ?P x&amp;quot;&lt;br /&gt;
 + Unificador de   &amp;quot;∃x. P x&amp;quot; y&lt;br /&gt;
                   &amp;quot;∃x. ?P x&amp;quot;&lt;br /&gt;
   es              ?P/P&lt;br /&gt;
 + Nuevo objetivo: &amp;quot;∀x. P x ⟹ P ?x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 apply (erule spec)&lt;br /&gt;
 + Objetivo:       &amp;quot;∀x. P x ⟹ P ?x&amp;quot;&lt;br /&gt;
 + spec:           &amp;quot;∀x. ?P x ⟹ ?P ?x&amp;quot;&lt;br /&gt;
 + Unificador de   (&amp;quot;?P ?x&amp;quot;, &amp;quot;∀x.  P x&amp;quot;) y&lt;br /&gt;
                   (&amp;quot;?P ?x&amp;quot;, &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
   es              ?P/P&lt;br /&gt;
 + Nuevo objetivo: Vacío, porque erule aplica assumption a &lt;br /&gt;
                    &amp;quot;P ?x ⟹ P ?x&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con allE y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (erule allE)  (* da P ?x ⟹ ∃x. P x*)&lt;br /&gt;
  apply (erule exI)   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Explicaciones&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  + Objetivo:       &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;?R&amp;quot;,      &amp;quot;∀x. ?P x&amp;quot;) y &lt;br /&gt;
                    (&amp;quot;∃x. P x&amp;quot;, &amp;quot;∀x. P  x&amp;quot;)&lt;br /&gt;
    es              ?R / ∃x. P x&lt;br /&gt;
                    ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;P ?x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule exI)&lt;br /&gt;
  + Objetivo:       &amp;quot;P ?x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  + exI:            &amp;quot;?P ?x ⟹ ∃x. ?P x&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;∃x. P  x&amp;quot;, &amp;quot;P ?x&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;∃x. ?P x&amp;quot;, &amp;quot;?P ?x&amp;quot;)&lt;br /&gt;
    es              ?P / P&lt;br /&gt;
                    ?x / x&lt;br /&gt;
  + Nuevo objetivo: Vacío&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con erule_tac *}  &lt;br /&gt;
lemma &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  apply (rule allI)              (* da ⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ &lt;br /&gt;
                                           ⟹ Q z *)&lt;br /&gt;
  apply (erule_tac x=z in allE)  (* da ⋀z. ⟦∀y. P y; P z ⟶ Q z⟧ &lt;br /&gt;
                                           ⟹ Q z *)&lt;br /&gt;
  apply (erule_tac x=z in allE)  (* da ⋀z. ⟦P z ⟶ Q z; P z⟧ ⟹ Q z *)&lt;br /&gt;
  apply (erule impE)             (* da ⋀z. P z ⟹ P z&lt;br /&gt;
                                       ⋀z. ⟦P z; Q z⟧ ⟹ Q z *)&lt;br /&gt;
   apply assumption+             (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
thm impE&lt;br /&gt;
&lt;br /&gt;
text {* Explicaciones&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  + allI:           &amp;quot;(⋀x. ?P x) ⟹ ∀x. ?P x&amp;quot;&lt;br /&gt;
  + Unificador de   &amp;quot;∀z. Q  z&amp;quot; y&lt;br /&gt;
                    &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
    es              ?P / Q&lt;br /&gt;
  + Ligadura:       ⋀x / ⋀z  &lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule_tac x=z in allE)&lt;br /&gt;
  + Objetivo:       &amp;quot;⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + allE &amp;quot;x=z&amp;quot;      &amp;quot;⟦∀x. ?P x; ?P z ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q z&amp;quot;, &amp;quot;∀x. P x ⟶ Q x&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,  &amp;quot;∀x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?R   / Q z&lt;br /&gt;
                    ?P x / P x ⟶ Q x&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦∀y. P y; P z ⟶ Q z⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + Nota: De &amp;quot;?P z ⟹ ?R&amp;quot; se obtiene la 2ª hipótesis y la conclusión.&lt;br /&gt;
&lt;br /&gt;
  apply (erule_tac x=z in allE)&lt;br /&gt;
  + Objetivo:       &amp;quot;⋀z. ⟦∀y. P y; P z ⟶ Q z⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + allE &amp;quot;x=z&amp;quot;      &amp;quot;⟦∀x. ?P x; ?P z ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q z&amp;quot;, &amp;quot;∀y. P  y&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,  &amp;quot;∀x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?R / Q z&lt;br /&gt;
                    ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦P z ⟶ Q z; P z⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + Nota: De &amp;quot;?P z ⟹ ?R&amp;quot; se obtiene la 2ª hipótesis y la conclusión.&lt;br /&gt;
&lt;br /&gt;
  apply (erule impE)&lt;br /&gt;
  + Objetivo: &amp;quot;⋀z. ⟦P z ⟶ Q z; P z⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + impE      &amp;quot;⟦?P ⟶ ?Q; ?P; ?Q ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de (&amp;quot;Q z&amp;quot;, &amp;quot;P z ⟶ Q z&amp;quot;) y&lt;br /&gt;
                  (&amp;quot;?R&amp;quot;,  &amp;quot;?P ⟶ ?Q&amp;quot;)&lt;br /&gt;
    es            ?R / Q z&lt;br /&gt;
                  ?P / P z&lt;br /&gt;
                  ?Q /Q z&lt;br /&gt;
  + Nuevos objetivos: &amp;quot;⋀z. P z ⟹ P z&amp;quot;&lt;br /&gt;
                      &amp;quot;⋀z. ⟦P z; Q z⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo sin erule_tac *}  &lt;br /&gt;
lemma &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  apply (rule allI)    (* da ⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z *)  &lt;br /&gt;
  apply (erule allE)   (* da ⋀z. ⟦∀y. P y; P (?x2 z) ⟶ Q (?x2 z)⟧ &lt;br /&gt;
                                 ⟹ Q z *)  &lt;br /&gt;
  apply (erule allE)   (* da ⋀z. ⟦P (?x2 z) ⟶ Q (?x2 z); P (?y4 z)⟧ &lt;br /&gt;
                                 ⟹ Q z *)  &lt;br /&gt;
  apply (erule mp)     (* da ⋀z. P (?y4 z) ⟹ P z *)  &lt;br /&gt;
  apply assumption     (* da No subgoals *)  &lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  + allI:           &amp;quot;(⋀x. ?P x) ⟹ ∀x. ?P x&amp;quot;&lt;br /&gt;
  + Unificador de   &amp;quot;∀z. Q  z&amp;quot; y&lt;br /&gt;
                    &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
    es              ?P / Q&lt;br /&gt;
  + Ligadura:       ⋀x / ⋀z &lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  + Objetivo:       &amp;quot;⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q z&amp;quot;, &amp;quot;∀x. P x ⟶ Q x&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,  &amp;quot;∀x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?R / Q z&lt;br /&gt;
                    ?P x / P x ⟶ Q x&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦∀y. P y; P (?x2 z) ⟶ Q (?x2 z)⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  + Objetivo:       &amp;quot;⋀z. ⟦∀y. P y; P (?x2 z) ⟶ Q (?x2 z)⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q z&amp;quot;, &amp;quot;∀y. P  y&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,  &amp;quot;∀x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?R / Q z&lt;br /&gt;
                    ?P / P &lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦P (?x2 z) ⟶ Q (?x2 z); P (?y4 z)⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  + Objetivo:       &amp;quot;⋀z. ⟦P (?x2 z) ⟶ Q (?x2 z); P (?y4 z)⟧ ⟹ Q z&amp;quot;&lt;br /&gt;
  + mp:             &amp;quot;⟦?P ⟶ ?Q; ?P⟧ ⟹ ?Q&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q z&amp;quot;, &amp;quot;P (?x2 z) ⟶ Q (?x2 z)&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?Q&amp;quot;, &amp;quot;?P ⟶ ?Q&amp;quot;)&lt;br /&gt;
    es              ?Q / Q z&lt;br /&gt;
                    ?x2 z/ z&lt;br /&gt;
                    ?P / P z&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. P (?y4 z) ⟹ P z&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con exE *}    &lt;br /&gt;
lemma &amp;quot;(∃z. P z) ∧ Q ⟶ (∃y. P y ∧ Q)&amp;quot;&lt;br /&gt;
  apply (rule impI)              (* da (∃z. P z) ∧ Q ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (erule conjE)            (* da ⟦∃z. P z; Q⟧ ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (erule exE)              (* da ⋀z. ⟦Q; P z⟧ ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;z&amp;quot; in exI)  (* da ⋀z. ⟦Q; P z⟧ ⟹ P z ∧ Q *)&lt;br /&gt;
  apply (rule conjI)             (* da ⋀z. ⟦Q; P z⟧ ⟹ P z&lt;br /&gt;
                                       ⋀z. ⟦Q; P z⟧ ⟹ Q *)&lt;br /&gt;
   apply assumption+             (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Explicaciones:&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  + Objetivo:       &amp;quot;(∃z. P z) ∧ Q ⟶ (∃y. P y ∧ Q)&amp;quot;&lt;br /&gt;
  + impI:           &amp;quot;(?P ⟹ ?Q) ⟹ ?P ⟶ ?Q&amp;quot;&lt;br /&gt;
  + Unificador de   &amp;quot;(∃z. P z) ∧ Q ⟶ (∃y. P y ∧ Q)&amp;quot; y&lt;br /&gt;
                    &amp;quot;?P ⟶ ?Q&amp;quot;&lt;br /&gt;
    es              ?P / &amp;quot;(∃z. P z) ∧ Q&amp;quot;&lt;br /&gt;
                    ?Q / &amp;quot;∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;(∃z. P z) ∧ Q ⟹ ∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule conjE)            &lt;br /&gt;
  + Objetivo:       &amp;quot;(∃z. P z) ∧ Q ⟹ ∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
  + conjE:          &amp;quot;⟦?P ∧ ?Q; ⟦?P; ?Q⟧ ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;∃y. P y ∧ Q&amp;quot;, &amp;quot;(∃z. P z) ∧ Q&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,          &amp;quot;?P ∧ ?Q&amp;quot;)&lt;br /&gt;
    es              ?R / &amp;quot;∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
                    ?P / &amp;quot;∃z. P z&amp;quot;&lt;br /&gt;
                    ?Q / Q&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦∃z. P z; Q⟧ ⟹ ∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule exE)              &lt;br /&gt;
  + Objetivo:       &amp;quot;⟦∃z. P z; Q⟧ ⟹ ∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
  + exE:            &amp;quot;⟦∃x. ?P x; ⋀x. ?P x ⟹ ?Q⟧ ⟹ ?Q&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;∃y. P y ∧ Q&amp;quot;, &amp;quot;∃z. P z&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?Q&amp;quot;,          &amp;quot;∃x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?Q / &amp;quot;∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
                    ?P x / P z&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦Q; P z⟧ ⟹ ∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (rule_tac x=&amp;quot;z&amp;quot; in exI)  &lt;br /&gt;
  + Objetivo:       &amp;quot;⋀z. ⟦Q; P z⟧ ⟹ ∃y. P y ∧ Q&amp;quot;&lt;br /&gt;
  + exI:            &amp;quot;?P ?x ⟹ ∃x. ?P x&amp;quot;&lt;br /&gt;
  + exI &amp;quot;x=z&amp;quot;       &amp;quot;?P z ⟹ ∃x. ?P x&amp;quot;&lt;br /&gt;
  + Unificador de   &amp;quot;∃y. P y ∧ Q&amp;quot; con&lt;br /&gt;
                    &amp;quot;∃x. ?P x&amp;quot;&lt;br /&gt;
    es              ?P x / P x ∧ Q&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀z. ⟦Q; P z⟧ ⟹ P z ∧ Q&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (rule conjI)             &lt;br /&gt;
  + Objetivo:         &amp;quot;⋀z. ⟦Q; P z⟧ ⟹ P z ∧ Q&amp;quot;&lt;br /&gt;
  + conjI:            &amp;quot;⟦?P; ?Q⟧ ⟹ ?P ∧ ?Q&amp;quot;&lt;br /&gt;
  + Unificador de     &amp;quot;P z ∧ Q&amp;quot; con&lt;br /&gt;
                      &amp;quot;?P ∧ ?Q&amp;quot;&lt;br /&gt;
    es                ?P / P z&lt;br /&gt;
                      ?Q / Q&lt;br /&gt;
  + Nuevos objetivos: &amp;quot;⋀z. ⟦Q; P z⟧ ⟹ P z&amp;quot;&lt;br /&gt;
                      &amp;quot;⋀z. ⟦Q; P z⟧ ⟹ Q&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Cálculo de secuentes de primer orden&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
lemma &amp;quot;A ⟹ ∀x. P x&amp;quot;&lt;br /&gt;
  apply (rule allI) (* da ⋀x. A ⟹ P x *)  &lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;A ⟹ ∀x. P x&amp;quot;&lt;br /&gt;
  + allI:           &amp;quot;(⋀x. ?P x) ⟹ ∀x. ?P x&amp;quot;&lt;br /&gt;
  + Unificador de   &amp;quot;∀x. P x&amp;quot; y &lt;br /&gt;
                    &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
   es               ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀x. A ⟹ P x&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule allE)   (* da ⟦A; P ?x⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  + allI:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q&amp;quot;, &amp;quot;∀x. P x&amp;quot;) y &lt;br /&gt;
                    (&amp;quot;?R·, &amp;quot;∀x. ?P x)&amp;quot;&lt;br /&gt;
   es               ?R / Q&lt;br /&gt;
                    ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦A; P ?x⟧ ⟹ Q&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule_tac x=t in allE)   (* da ⟦A; P t⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + allE &amp;quot;x=t&amp;quot;      &amp;quot;⟦∀x. ?P x; ?P t ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;Q&amp;quot;, &amp;quot;∀x. P x&amp;quot;) y &lt;br /&gt;
                    (&amp;quot;?R·, &amp;quot;∀x. ?P x)&amp;quot;&lt;br /&gt;
   es               ?R / Q&lt;br /&gt;
                    ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦A; P ?t⟧ ⟹ Q&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (frule spec) (* da ⟦A; ∀x. P x; P ?x⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  + spec:           &amp;quot;∀x. ?P x ⟹ ?P ?x&amp;quot; &lt;br /&gt;
  + Unificador de   &amp;quot;∀x. P x&amp;quot; y &lt;br /&gt;
                    &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
   es               ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦A; ∀x. P x; P ?x⟧ ⟹ Q&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (frule_tac x=t in spec) (* da ⟦A; ∀x. P x; P t⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  + spec:           &amp;quot;∀x. ?P x ⟹ ?P ?x&amp;quot; &lt;br /&gt;
  + spec &amp;quot;x=t&amp;quot;      &amp;quot;∀x. ?P x ⟹ ?P t&amp;quot; &lt;br /&gt;
  + Unificador de   &amp;quot;∀x. P x&amp;quot; y &lt;br /&gt;
                    &amp;quot;∀x. ?P x&amp;quot;&lt;br /&gt;
   es               ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦A; ∀x. P x; P t⟧ ⟹ Q&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule exI) (* da A ⟹ P ?x *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  + spec:           &amp;quot;?P ?x ⟹ ∃x. ?P x&amp;quot; &lt;br /&gt;
  + Unificador de   &amp;quot;∃x. P x&amp;quot; y &lt;br /&gt;
                    &amp;quot;∃x. ?P x&amp;quot;&lt;br /&gt;
   es               ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;A ⟹ P ?x&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule_tac x=t in exI) (* da A ⟹ P t *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  + spec:           &amp;quot;?P ?x ⟹ ∃x. ?P x&amp;quot; &lt;br /&gt;
  + spec &amp;quot;x=t&amp;quot;:     &amp;quot;?P t ⟹ ∃x. ?P x&amp;quot; &lt;br /&gt;
  + Unificador de   &amp;quot;∃x. P x&amp;quot; y &lt;br /&gt;
                    &amp;quot;∃x. ?P x&amp;quot;&lt;br /&gt;
   es               ?P / P&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;A ⟹ P t&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∃x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule exE)  (* da ⋀x. ⟦A; P x⟧ ⟹ Q *)&lt;br /&gt;
  oops  &lt;br /&gt;
&lt;br /&gt;
text {* Explicación&lt;br /&gt;
  + Objetivo:       &amp;quot;⟦A; ∃x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  + exE:            &amp;quot;⟦∃x. ?P x; ⋀x. ?P x ⟹ ?Q⟧ ⟹ ?Q&amp;quot; &lt;br /&gt;
  + Unificador de   (&amp;quot;Q&amp;quot;, &amp;quot;∃x. P x&amp;quot; y &lt;br /&gt;
                    (&amp;quot;?Q&amp;quot;, &amp;quot;∃x. ?P x&amp;quot;&lt;br /&gt;
   es               ?Q / Q&lt;br /&gt;
                    ?P / P &lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⋀x. ⟦A; P x⟧ ⟹ Q&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Ejemplos del tema 6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Reglas del cuantificador universal *}&lt;br /&gt;
&lt;br /&gt;
lemma ej1: &amp;quot;⟦P(c); ∀x. (P(x) ⟶ ¬Q(x))⟧ ⟹ ¬Q(c)&amp;quot;&lt;br /&gt;
  apply (erule allE) (* da ⟦P c; P ?x ⟶ ¬ Q ?x⟧ ⟹ ¬ Q c *)&lt;br /&gt;
  apply (erule mp)   (* da P c ⟹ P c *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* Explicaciones&lt;br /&gt;
  apply (erule allE) &lt;br /&gt;
  + Objetivo:       &amp;quot;⟦P(c); ∀x. (P(x) ⟶ ¬Q(x))⟧ ⟹ ¬Q(c)&amp;quot;&lt;br /&gt;
  + allE:           &amp;quot;⟦∀x. ?P x; ?P ?x ⟹ ?R⟧ ⟹ ?R&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;¬Q(c)&amp;quot;, &amp;quot;∀x. (P(x) ⟶ ¬Q(x))&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?R&amp;quot;,    &amp;quot;∀x. ?P x&amp;quot;)&lt;br /&gt;
    es              ?R / ¬Q(c)&lt;br /&gt;
                    ?P x / P(x) ⟶ ¬Q(x) &lt;br /&gt;
  + Nuevo objetivo: &amp;quot;⟦P c; P ?x ⟶ ¬ Q ?x⟧ ⟹ ¬ Q c&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  apply (erule mp)   &lt;br /&gt;
  + Objetivo:       &amp;quot;⟦P c; P ?x ⟶ ¬ Q ?x⟧ ⟹ ¬ Q c&amp;quot;&lt;br /&gt;
  + mp:             &amp;quot;⟦?P ⟶ ?Q; ?P⟧ ⟹ ?Q&amp;quot;&lt;br /&gt;
  + Unificador de   (&amp;quot;¬ Q c&amp;quot;, &amp;quot;P ?x ⟶ ¬ Q ?x&amp;quot;) y&lt;br /&gt;
                    (&amp;quot;?Q&amp;quot;,    &amp;quot;?P ⟶ ?Q&amp;quot;)&lt;br /&gt;
    es              ?Q / ¬ Q c&lt;br /&gt;
                    ?P / P c&lt;br /&gt;
  + Nuevo objetivo: &amp;quot;P c ⟹ P c&amp;quot; &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ej2: &amp;quot;⟦∀x. (P x ⟶ ¬(Q x)); ∀y. P y⟧ ⟹ ∀z. ¬(Q z)&amp;quot;&lt;br /&gt;
  apply (rule allI)   (* da ⋀z. ⟦P (?x2 z) ⟶ ¬ Q (?x2 z);&lt;br /&gt;
                                 P (?y4 z)⟧&lt;br /&gt;
                                ⟹ ¬ Q z*)&lt;br /&gt;
  apply (erule allE)+ (* da ⋀z. ⟦P (?x2 z) ⟶ ¬ Q (?x2 z);&lt;br /&gt;
                                 P (?y4 z)⟧&lt;br /&gt;
                                ⟹ ¬ Q z *)&lt;br /&gt;
  apply (erule mp)    (* da ⋀z. P (?y4 z) ⟹ P z *)&lt;br /&gt;
  apply assumption    (* da No subgoals! *) &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Reglas del cuantificador existencial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma ej3: &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
  apply (erule allE) (* da P ?x ⟹ ∃y. P y *)&lt;br /&gt;
  apply (erule exI)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej4: &amp;quot;⟦∀x. P x ⟶ Q x; ∃y. P y⟧ ⟹ ∃z. Q z&amp;quot;&lt;br /&gt;
  apply (erule exE)  (* da ⋀y. ⟦∀x. P x ⟶ Q x; P y⟧ ⟹ ∃z. Q z *)&lt;br /&gt;
  apply (erule allE) (* da ⋀y. ⟦P y; P (?x2 y) ⟶ Q (?x2 y)⟧ ⟹ ∃z. Q z *)&lt;br /&gt;
  apply (rule exI)   (* da ⋀y. ⟦P y; P (?x2 y) ⟶ Q (?x2 y)⟧ ⟹ Q (?z4 y) *)&lt;br /&gt;
  apply (erule mp)   (* da ⋀y. P y ⟹ P (?x2 y) *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Demostraciones de equivalencias&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma ej5a: &amp;quot;¬(∀x. P x) ⟹ ∃y. ¬P y&amp;quot;&lt;br /&gt;
  apply (rule ccontr) (* da ⟦¬ (∀x. P x); ∄y. ¬ P y⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)  (* da ∄y. ¬ P y ⟹ ∀x. P x *)&lt;br /&gt;
  apply (rule allI)   (* da ⋀x. ∄y. ¬ P y ⟹ P x *)&lt;br /&gt;
  apply (rule ccontr) (* da ⋀x. ⟦∄y. ¬ P y; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE)  (* da ⋀x. ¬ P x ⟹ ∃y. ¬ P y *)&lt;br /&gt;
   apply (erule exI)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej5b: &amp;quot;∃x. ¬P x ⟹ ¬(∀y. P y)&amp;quot;&lt;br /&gt;
  apply (rule notI)  (* da ⟦∃x. ¬ P x; ∀y. P y⟧ ⟹ False *)&lt;br /&gt;
  apply (erule exE)  (* da ⋀x. ⟦∀y. P y; ¬ P x⟧ ⟹ False *)&lt;br /&gt;
  apply (erule allE) (* da ⋀x. ⟦¬ P x; P (?y4 x)⟧ ⟹ False *)&lt;br /&gt;
  apply (erule notE) (* da ⋀x. P (?y4 x) ⟹ P x *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej5: &amp;quot;¬(∀x. P x) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)    (* da ¬ (∀x. P x) ⟹ ∃x. ¬ P x&lt;br /&gt;
                             ∃x. ¬ P x ⟹ ¬ (∀x. P x) *)&lt;br /&gt;
   apply (erule ej5a)  (* da ∃x. ¬ P x ⟹ ¬ (∀x. P x) *)&lt;br /&gt;
  apply (erule ej5b)   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6a: &amp;quot;∀x. P(x) ∧ Q(x) ⟹ (∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule conjI)    (* da ∀x. P x ∧ Q x ⟹ ∀x. P x&lt;br /&gt;
                              ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
   apply (rule allI)    (* da ⋀x. ∀x. P x ∧ Q x ⟹ P x&lt;br /&gt;
                              ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
   apply (erule allE)   (* da ⋀x. P (?x5 x) ∧ Q (?x5 x) ⟹ P x&lt;br /&gt;
                              ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
   apply (erule conjE)  (* da ⋀x. ⟦P (?x5 x); Q (?x5 x)⟧ ⟹ P x&lt;br /&gt;
                              ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
   apply assumption     (* da ∀x. P x ∧ Q x ⟹ ∀x. Q x *)&lt;br /&gt;
  apply (rule allI)     (* da ⋀x. ∀x. P x ∧ Q x ⟹ Q x *)&lt;br /&gt;
  apply (erule allE)    (* da ⋀x. P (?x11 x) ∧ Q (?x11 x) ⟹ Q x *)&lt;br /&gt;
  apply (erule conjE)   (* da ⋀x. ⟦P (?x11 x); Q (?x11 x)⟧ ⟹ Q x *)&lt;br /&gt;
  apply assumption      (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6b: &amp;quot;(∀x. P x) ∧ (∀x. Q x) ⟹ ∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  apply (rule allI)        (* da ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ P x ∧ Q x *) &lt;br /&gt;
  apply (rule conjI)       (* da ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ P x&lt;br /&gt;
                                 ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ Q x *)&lt;br /&gt;
   apply (drule conjunct1) (* da ⋀x. ∀x. P x ⟹ P x&lt;br /&gt;
                                 ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ Q x*)&lt;br /&gt;
   apply (erule spec)      (* da ⋀x. (∀x. P x) ∧ (∀x. Q x) ⟹ Q x *)&lt;br /&gt;
   apply (drule conjunct2) (* da ⋀x. ∀x. Q x ⟹ Q x *)&lt;br /&gt;
  apply (erule spec)       (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6: &amp;quot;(∀x. P x ∧ Q x) ⟷ (∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)   (* da ∀x. P x ∧ Q x ⟹ (∀x. P x) ∧ (∀x. Q x)&lt;br /&gt;
                            (∀x. P x) ∧ (∀x. Q x) ⟹ ∀x. P x ∧ Q x *)&lt;br /&gt;
   apply (erule ej6a) (* da (∀x. P x) ∧ (∀x. Q x) ⟹ ∀x. P x ∧ Q x *)&lt;br /&gt;
  apply (erule ej6b)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7a: &amp;quot;(∃x. P x) ∨ (∃x. Q x) ⟹ ∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  apply (erule disjE)   (* da ∃x. P x ⟹ ∃x. P x ∨ Q x&lt;br /&gt;
                              ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
   apply (erule exE)    (* da ⋀x. P x ⟹ ∃x. P x ∨ Q x&lt;br /&gt;
                              ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
   apply (rule exI)     (* da ⋀x. P x ⟹ P (?x5 x) ∨ Q (?x5 x) &lt;br /&gt;
                              ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
   apply (erule disjI1) (* da ∃x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
  apply (erule exE)     (* da ⋀x. Q x ⟹ ∃x. P x ∨ Q x *)&lt;br /&gt;
  apply (rule exI)      (* da ⋀x. Q x ⟹ P (?x10 x) ∨ Q (?x10 x) *)&lt;br /&gt;
  apply (erule disjI2)  (* da No subgoals! *) &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7b: &amp;quot;∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  apply (erule exE)    (* da ⋀x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x)*)&lt;br /&gt;
  apply (erule disjE)  (* da ⋀x. P x ⟹ (∃x. P x) ∨ (∃x. Q x)&lt;br /&gt;
                             ⋀x. Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
   apply (rule disjI1) (* da ⋀x. P x ⟹ ∃x. P x&lt;br /&gt;
                             ⋀x. Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
   apply (erule exI)   (* da ⋀x. Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
  apply (rule disjI2)  (* da  ⋀x. Q x ⟹ ∃x. Q x *)&lt;br /&gt;
  apply (erule exI)    (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7: &amp;quot;(∃x. P x) ∨ (∃x. Q x) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)   (* da (∃x. P x) ∨ (∃x. Q x) ⟹ ∃x. P x ∨ Q x&lt;br /&gt;
                            ∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *) &lt;br /&gt;
   apply (erule ej7a) (* da ∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x) *)&lt;br /&gt;
  apply (erule ej7b)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8a: &amp;quot;∃x y. P x y ⟹ ∃y x. P x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+ (* da ⋀x y. P x y ⟹ ∃y x. P x y *)&lt;br /&gt;
  apply (rule exI)+  (* da ⋀x y. P x y ⟹ P (?x6 x y) (?y4 x y) *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8b: &amp;quot;∃y x. P x y ⟹ ∃x y. P x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+ (* da ⋀y x. P x y ⟹ ∃x y. P x *)&lt;br /&gt;
  apply (rule exI)+  (* da ⋀y x. P x y ⟹ P (?x4 y x) (?y6 y x)*)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej8: &amp;quot;(∃x y. P x y) ⟷ (∃y x. P x y)&amp;quot;&lt;br /&gt;
  apply (rule iffI)   (* da ∃x y. P x y ⟹ ∃y x. P x y&lt;br /&gt;
                            ∃y x. P x y ⟹ ∃x y. P x y *)&lt;br /&gt;
   apply (erule ej8a) (* da ∃y x. P x y ⟹ ∃x y. P x y *)&lt;br /&gt;
  apply (erule ej8b)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_proposicional_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=484</id>
		<title>Deducción natural proposicional con Isabelle/HOL basada en tácticas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_proposicional_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=484"/>
		<updated>2019-03-26T06:19:34Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
theory T2b&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Introducción&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Enunciado de teoremas&amp;quot;  &lt;br /&gt;
  &lt;br /&gt;
theorem primerEjemplo: &amp;quot;(A ⟶ B) ∨ (B ⟶ A)&amp;quot;&lt;br /&gt;
oops  &lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Demostración por asunción&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; B; C⟧ ⟹ B&amp;quot;&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Ejemplo de aplicación de rule&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* 1º ejemplo de aplicación de rule *}&lt;br /&gt;
lemma &amp;quot;A ∧ B ⟹ B ∧ A&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* 2º ejemplo de aplicación de rule *}&lt;br /&gt;
lemma &amp;quot;A ∧ B ⟹ B ∨ A&amp;quot;&lt;br /&gt;
  apply (rule disjI1)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦(A ∧ B) ∨ C; D⟧ ⟹ B ∨ C&amp;quot;    &lt;br /&gt;
  apply (rule disjE)&lt;br /&gt;
    apply assumption&lt;br /&gt;
  oops   &lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Ejemplo de demostración con rule y assumption&amp;quot;&lt;br /&gt;
&lt;br /&gt;
theorem K: &amp;quot;A ⟶ (B ⟶ A)&amp;quot;&lt;br /&gt;
  apply (rule impI)  (* da  A ⟹ B ⟶ A *)&lt;br /&gt;
  apply (rule impI)  (* da ⟦A; B⟧ ⟹ A *)&lt;br /&gt;
  apply assumption   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Ejemplo de derivación con hipótesis&amp;quot;    &lt;br /&gt;
        &lt;br /&gt;
text {* Derivación de A, B ⊢ A ∧ (B ∧ A) *}&lt;br /&gt;
theorem &amp;quot;⟦A; B⟧ ⟹ A ∧ (B ∧ A)&amp;quot;&lt;br /&gt;
  apply (rule conjI)  (* da ⟦A; B⟧ ⟹ A&lt;br /&gt;
                            ⟦A; B⟧ ⟹ B ∧ A *)&lt;br /&gt;
   apply assumption   (* da ⟦A; B⟧ ⟹ B ∧ A *)&lt;br /&gt;
  apply (rule conjI)  (* da ⟦A; B⟧ ⟹ B&lt;br /&gt;
                            ⟦A; B⟧ ⟹ A *)&lt;br /&gt;
   apply assumption   (* da ⟦A; B⟧ ⟹ A *)&lt;br /&gt;
  apply assumption    (* da No subgoals *)&lt;br /&gt;
  done &lt;br /&gt;
&lt;br /&gt;
text {* La prueba anterior se puede simplificar usando assumption+ *}&lt;br /&gt;
theorem &amp;quot;⟦A; B⟧ ⟹ A ∧ (B ∧ A)&amp;quot;&lt;br /&gt;
  apply (rule conjI)  (* da ⟦A; B⟧ ⟹ A&lt;br /&gt;
                            ⟦A; B⟧ ⟹ B ∧ A *)&lt;br /&gt;
   apply assumption   (* da ⟦A; B⟧ ⟹ B ∧ A *)&lt;br /&gt;
  apply (rule conjI)  (* da ⟦A; B⟧ ⟹ B&lt;br /&gt;
                            ⟦A; B⟧ ⟹ A *)&lt;br /&gt;
   apply assumption+  (* da No subgoals *)&lt;br /&gt;
  done &lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Ejemplo de aplicación de erule&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦(A ∧ B) ∨ C; D⟧ ⟹ B ∨ C&amp;quot;    &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Demostración con erule *}    &lt;br /&gt;
lemma &amp;quot;A ∨ B ⟹ B ∨ A&amp;quot;&lt;br /&gt;
  apply (erule disjE)   (* da A ⟹ B ∨ A&lt;br /&gt;
                              B ⟹ B ∨ A*)&lt;br /&gt;
   apply (rule disjI2)  (* da A ⟹ A&lt;br /&gt;
                              B ⟹ B ∨ A *)&lt;br /&gt;
   apply assumption     (* da B ⟹ B ∨ A *)&lt;br /&gt;
  apply (rule disjI1)   (* da B ⟹ B *)&lt;br /&gt;
  apply assumption      (* da No subgoals *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Variación de la demostración anterior cambiando erule por rule *}&lt;br /&gt;
lemma &amp;quot;A ∨ B ⟹ B ∨ A&amp;quot;&lt;br /&gt;
  apply (rule disjE)    (* da A ∨ B ⟹ ?P ∨ ?Q&lt;br /&gt;
                              ⟦A ∨ B; ?P⟧ ⟹ B ∨ A&lt;br /&gt;
                              ⟦A ∨ B; ?Q⟧ ⟹ B ∨ A *)&lt;br /&gt;
    apply assumption    (* da ⟦A ∨ B; A⟧ ⟹ B ∨ A&lt;br /&gt;
                              ⟦A ∨ B; B⟧ ⟹ B ∨ A *) &lt;br /&gt;
   apply (rule disjI2)  (* da ⟦A ∨ B; A⟧ ⟹ A&lt;br /&gt;
                              ⟦A ∨ B; B⟧ ⟹ B ∨ A*)&lt;br /&gt;
   apply assumption     (* da ⟦A ∨ B; B⟧ ⟹ B ∨ A *)&lt;br /&gt;
  apply (rule disjI1)   (* da ⟦A ∨ B; B⟧ ⟹ B *)&lt;br /&gt;
  apply assumption      (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Ejemplo de aplicación de drule&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A ⟶ B; A ∧ C⟧ ⟹ B ∧ C&amp;quot;    &lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Demostración con drule *}    &lt;br /&gt;
lemma &amp;quot;A ∧ B ⟹ A&amp;quot;&lt;br /&gt;
  apply (drule conjunct1) (* da A ⟹ A *)&lt;br /&gt;
  apply assumption        (* da No subgoals! *)&lt;br /&gt;
  done   &lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Ejemplo de aplicación de frule&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A ⟶ B; A ∧ C⟧ ⟹ B ∧ C&amp;quot;    &lt;br /&gt;
  apply (frule mp)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Demostración con frule *}    &lt;br /&gt;
lemma &amp;quot;A ∧ B ⟹ A&amp;quot;&lt;br /&gt;
  apply (frule conjunct1)  (* da ⟦A ∧ B; A⟧ ⟹ A *)&lt;br /&gt;
  apply assumption         (* da No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
  &lt;br /&gt;
subsection &amp;quot;Ejemplo de aplicación de erule_tac&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A ∧ B; C ∧ (B ∧ D)⟧ ⟹ B ∧ D&amp;quot;&lt;br /&gt;
  apply (erule_tac Q=&amp;quot;B ∧ D&amp;quot; in conjE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A ∧ B; C ∧ (B ∧ D)⟧ ⟹ B ∧ D&amp;quot;&lt;br /&gt;
  apply (erule conjE)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* Demostración con erule_tac *}    &lt;br /&gt;
lemma &amp;quot;⟦A ∧ B; C ∧ D⟧ ⟹ D&amp;quot;&lt;br /&gt;
  apply (erule_tac P=C in conjE)  (* da ⟦A ∧ B; C; D⟧ ⟹ D *)&lt;br /&gt;
  apply assumption                (* da No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
    &lt;br /&gt;
text {* Demostración sin erule_tac *}    &lt;br /&gt;
lemma &amp;quot;⟦A ∧ B; C ∧ D⟧ ⟹ D&amp;quot;&lt;br /&gt;
  apply (erule conjE)  (* da ⟦C ∧ D; A; B⟧ ⟹ D *)&lt;br /&gt;
  apply (erule conjE)  (* da ⟦A; B; C; D⟧ ⟹ D *)&lt;br /&gt;
  apply assumption     (* da No subgoals! *)&lt;br /&gt;
  done  &lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Cálculo de secuentes&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ P ∧ Q&amp;quot;  &lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A; P ∧ Q⟧ ⟹ R&amp;quot;&lt;br /&gt;
  apply (erule conjE)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ P ∨ Q&amp;quot;&lt;br /&gt;
  apply (rule disjI1)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ P ∨ Q&amp;quot;&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A; P ∨ Q⟧ ⟹ R&amp;quot;&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ P ⟶ Q&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; P ⟶ Q⟧ ⟹ R&amp;quot;&lt;br /&gt;
  apply (erule impE)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A; False⟧ ⟹ P&amp;quot;&lt;br /&gt;
  apply (erule FalseE)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ ¬P&amp;quot;&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A; P; ¬P⟧ ⟹ R&amp;quot;&lt;br /&gt;
  apply (erule notE, assumption)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;A ⟹ ¬P ∨ P&amp;quot;&lt;br /&gt;
  apply (rule excluded_middle)&lt;br /&gt;
  done   &lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Ejemplos de pruebas&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
lemma &amp;quot;((S ∨ R) ∧ ¬S) ⟶ R&amp;quot; &lt;br /&gt;
  apply (rule impI)        (* da (S ∨ R) ∧ ¬ S ⟹ R *)&lt;br /&gt;
  apply (frule conjunct1)  (* da ⟦(S ∨ R) ∧ ¬ S; S ∨ R⟧ ⟹ R *)&lt;br /&gt;
  apply (erule disjE)      (* da ⟦(S ∨ R) ∧ ¬ S; S⟧ ⟹ R&lt;br /&gt;
                                 ⟦(S ∨ R) ∧ ¬ S; R⟧ ⟹ R *)&lt;br /&gt;
   apply (drule conjunct2) (* da ⟦S; ¬ S⟧ ⟹ R&lt;br /&gt;
                                 ⟦(S ∨ R) ∧ ¬ S; R⟧ ⟹ R *)&lt;br /&gt;
   apply (erule notE)      (* da S ⟹ S&lt;br /&gt;
                                 ⟦(S ∨ R) ∧ ¬ S; R⟧ ⟹ R *)&lt;br /&gt;
   apply assumption+       (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
lemma &amp;quot;(C ∨ P) ∧ (C ⟶ S) ∧ ¬P ⟶ S&amp;quot;&lt;br /&gt;
  apply (rule impI)     (* da (C ∨ P) ∧ (C ⟶ S) ∧ ¬ P ⟹ S *)&lt;br /&gt;
  apply (erule conjE)+  (* da ⟦C ∨ P; C ⟶ S; ¬ P⟧ ⟹ S *)&lt;br /&gt;
  apply (erule disjE)   (* da ⟦C ⟶ S; ¬ P; C⟧ ⟹ S&lt;br /&gt;
                              ⟦C ⟶ S; ¬ P; P⟧ ⟹ S *)&lt;br /&gt;
   apply (erule impE)   (* da ⟦¬ P; C⟧ ⟹ C&lt;br /&gt;
                              ⟦¬ P; C; S⟧ ⟹ S&lt;br /&gt;
                              ⟦C ⟶ S; ¬ P; P⟧ ⟹ S *)&lt;br /&gt;
    apply assumption+   (* da ⟦C ⟶ S; ¬ P; P⟧ ⟹ S *)&lt;br /&gt;
  apply (erule notE)    (* da ⟦C ⟶ S; P⟧ ⟹ P *)&lt;br /&gt;
  apply assumption      (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;La regla de corte&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
lemma aux: &amp;quot;A ⟹ A ∨ B&amp;quot;&lt;br /&gt;
  sorry&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;P ∧ Q ⟹ Q&amp;quot;&lt;br /&gt;
  apply (cut_tac aux) &lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;¬(¬p ∧ ¬q) ⟹ p ∨ q&amp;quot;&lt;br /&gt;
  apply (cut_tac P=p in excluded_middle)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (cut_tac P=q in excluded_middle)&lt;br /&gt;
   apply (erule disjE)&lt;br /&gt;
    apply (erule notE)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
     apply assumption+&lt;br /&gt;
   apply (erule disjI2)&lt;br /&gt;
  apply (erule disjI1)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* Ejemplo de case_tac *}&lt;br /&gt;
lemma &amp;quot;P ∧ Q ⟹ Q&amp;quot;&lt;br /&gt;
  apply (case_tac &amp;quot;P&amp;quot;) (* da ⟦P ∧ Q; P⟧ ⟹ Q&lt;br /&gt;
                             ⟦P ∧ Q; ¬ P⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {* La demostración anterior usando case_tac *}    &lt;br /&gt;
lemma &amp;quot;¬(¬p ∧ ¬q) ⟹ p ∨ q&amp;quot;&lt;br /&gt;
  apply (case_tac p)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (case_tac q)&lt;br /&gt;
  apply (erule disjI2)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
  apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Ejemplo de demostración automática&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A ∧ B; C ∧ (B ∧ D)⟧ ⟹ B ∧ D&amp;quot;&lt;br /&gt;
  apply simp&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Ejemplos del tema 2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Reglas de la conjunción *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 1 (p. 4). Demostrar que&lt;br /&gt;
     p ∧ q, r ⊢ q ∧ r.&lt;br /&gt;
  *}     &lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_1:  &amp;quot;⟦p ∧ q; r⟧ ⟹ q ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  apply assumption  &lt;br /&gt;
  done  &lt;br /&gt;
     &lt;br /&gt;
subsection {* Reglas de la doble negación *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La regla de eliminación de la doble negación es&lt;br /&gt;
  · notnotD: ¬¬ P ⟹ P&lt;br /&gt;
&lt;br /&gt;
  Para ajustarnos al tema de LI vamos a introducir la siguiente regla de&lt;br /&gt;
  introducción de la doble negación&lt;br /&gt;
  · notnotI: P ⟹ ¬¬ P&lt;br /&gt;
  aunque, de momento, no detallamos su demostración.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma notnotI [intro!]: &amp;quot;P ⟹ ¬¬ P&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 2. (p. 5)&lt;br /&gt;
       p, ¬¬(q ∧ r) ⊢ ¬¬p ∧ r&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_2_A: &amp;quot;⟦p; ¬¬(q ∧ r) ⟧ ⟹ ¬¬p ∧ r&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (rule notnotI)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule notnotD)&lt;br /&gt;
  apply (erule conjunct2)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
subsection {* Regla de eliminación del condicional *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La regla de eliminación del condicional es la regla del modus ponens&lt;br /&gt;
  · mp: ⟦P ⟶ Q; P⟧ ⟹ Q &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 3. (p. 6) Demostrar que&lt;br /&gt;
     ¬p ∧ q, ¬p ∧ q ⟶ r ∨ ¬p ⊢ r ∨ ¬p&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_3: &amp;quot;⟦¬p ∧ q; ¬p ∧ q ⟶ r ∨ ¬p⟧ ⟹ r ∨ ¬p&amp;quot;&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 4 (p. 6) Demostrar que&lt;br /&gt;
     p, p ⟶ q, p ⟶ (q ⟶ r) ⊢ r&lt;br /&gt;
 *}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_4: &amp;quot;⟦p; p ⟶ q; p ⟶ (q ⟶ r)⟧ ⟹ r&amp;quot;&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done    &lt;br /&gt;
      &lt;br /&gt;
subsection {* Regla derivada del modus tollens *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Para ajustarnos al tema de LI vamos a introducir la regla del modus&lt;br /&gt;
  tollens&lt;br /&gt;
  · mt: ⟦F ⟶ G; ¬G⟧ ⟹ ¬F &lt;br /&gt;
  aunque, de momento, sin detallar su demostración.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma mt: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;&lt;br /&gt;
by auto&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 5 (p. 7). Demostrar&lt;br /&gt;
     p ⟶ (q ⟶ r), p, ¬r ⊢ ¬q&lt;br /&gt;
 *}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_5_: &amp;quot;⟦p ⟶ (q ⟶ r); p; ¬r ⟧ ⟹ ¬q&amp;quot;&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 6. (p. 7) Demostrar &lt;br /&gt;
     ¬p ⟶ q, ¬q ⊢ p&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_6: &amp;quot;⟦¬p ⟶ q; ¬q⟧ ⟹ p&amp;quot;  &lt;br /&gt;
  apply (drule mt)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notnotD)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 7. (p. 7) Demostrar&lt;br /&gt;
     p ⟶ ¬q, q ⊢ ¬p&lt;br /&gt;
  *}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_7: &amp;quot;⟦p ⟶ ¬q; q⟧ ⟹ ¬p&amp;quot;  &lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply (erule notnotI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection {* Regla de introducción del condicional *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La regla de introducción del condicional es&lt;br /&gt;
  · impI: (P ⟹ Q) ⟹ P ⟶ Q&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 8. (p. 8) Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬q ⟶ ¬p&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_8: &amp;quot;p ⟶ q ⟹ ¬q ⟶ ¬p&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 9. (p. 9) Demostrar&lt;br /&gt;
     ¬q ⟶ ¬p ⊢ p ⟶ ¬¬q&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_9: &amp;quot;¬q ⟶ ¬p ⟹ p ⟶ ¬¬q&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule mt)&lt;br /&gt;
  apply (rule notnotI)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 10 (p. 9). Demostrar&lt;br /&gt;
     ⊢ p ⟶ p&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_10: &amp;quot;p ⟶ p&amp;quot;&lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 11 (p. 10) Demostrar&lt;br /&gt;
     ⊢ (q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&lt;br /&gt;
 *}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_11_A: &amp;quot;(q ⟶ r) ⟶ ((¬q ⟶ ¬p) ⟶ (p ⟶ r))&amp;quot;  &lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply (drule mt)&lt;br /&gt;
   apply (rule notnotI)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (rule notnotD)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection {* Reglas de la disyunción *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Las reglas de la introducción de la disyunción son&lt;br /&gt;
  · disjI1: P ⟹ P ∨ Q&lt;br /&gt;
  · disjI2: Q ⟹ P ∨ Q&lt;br /&gt;
  La regla de elimación de la disyunción es&lt;br /&gt;
  · disjE:  ⟦P ∨ Q; P ⟹ R; Q ⟹ R⟧ ⟹ R &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 12 (p. 11). Demostrar&lt;br /&gt;
     p ∨ q ⊢ q ∨ p&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_12: &amp;quot;p ∨ q ⟹ q ∨ p&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI2)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   apply assumption+ &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 13. (p. 12) Demostrar&lt;br /&gt;
     q ⟶ r ⊢ p ∨ q ⟶ p ∨ r&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_13_A: &amp;quot;q ⟶ r ⟹ p ∨ q ⟶ p ∨ r&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   prefer 2&lt;br /&gt;
   apply (drule mp)&lt;br /&gt;
  prefer 2&lt;br /&gt;
    apply (rule disjI2)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
subsection {* Regla de copia *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 14 (p. 13). Demostrar&lt;br /&gt;
     ⊢ p ⟶ (q ⟶ p)&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_14_A: &amp;quot;p ⟶ (q ⟶ p)&amp;quot;  &lt;br /&gt;
  apply (rule impI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection {* Reglas de la negación *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La regla de eliminación de lo falso es&lt;br /&gt;
  · FalseE: False ⟹ P&lt;br /&gt;
  La regla de eliminación de la negación es&lt;br /&gt;
  · notE: ⟦¬P; P⟧ ⟹ R&lt;br /&gt;
  La regla de introducción de la negación es&lt;br /&gt;
  · notI: (P ⟹ False) ⟹ ¬P&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 15 (p. 15). Demostrar&lt;br /&gt;
     ¬p ∨ q ⊢ p ⟶ q&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_15: &amp;quot;¬p ∨ q ⟹ p ⟶ q&amp;quot;  &lt;br /&gt;
  apply (rule impI)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 16 (p. 16). Demostrar&lt;br /&gt;
     p ⟶ q, p ⟶ ¬q ⊢ ¬p&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_16_A: &amp;quot;⟦p ⟶ q; p ⟶ ¬q⟧ ⟹ ¬p&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule mp)+&lt;br /&gt;
    apply assumption+&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
    prefer 2&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
subsection {* Reglas del bicondicional *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La regla de introducción del bicondicional es&lt;br /&gt;
  · iffI: ⟦P ⟹ Q; Q ⟹ P⟧ ⟹ P ⟷ Q&lt;br /&gt;
  Las reglas de eliminación del bicondicional son&lt;br /&gt;
  · iffD1: ⟦Q ⟷ P; Q⟧ ⟹ P &lt;br /&gt;
  · iffD2: ⟦P ⟷ Q; Q⟧ ⟹ P&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 17 (p. 17) Demostrar&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_17: &amp;quot;(p ∧ q) ⟷ (q ∧ p)&amp;quot;  &lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (rule conjI)&lt;br /&gt;
    apply (erule conjunct2)&lt;br /&gt;
   apply (erule conjunct1)&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
    apply (erule conjunct2)&lt;br /&gt;
  apply (erule conjunct1)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 18 (p. 18). Demostrar&lt;br /&gt;
     p ⟷ q, p ∨ q ⊢ p ∧ q&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_18_A: &amp;quot;⟦p ⟷ q; p ∨ q⟧ ⟹ p ∧ q&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule conjI)&lt;br /&gt;
    apply assumption&lt;br /&gt;
    apply (erule iffD1)&lt;br /&gt;
    apply assumption&lt;br /&gt;
    apply (rule conjI)&lt;br /&gt;
    apply (erule iffD2)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection {* Reglas derivadas *}&lt;br /&gt;
&lt;br /&gt;
subsubsection {* Regla del modus tollens *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 19 (p. 20) Demostrar la regla del modus tollens a partir de&lt;br /&gt;
  las reglas básicas. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_20: &amp;quot;⟦F ⟶ G; ¬G⟧ ⟹ ¬F&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (drule mp)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsubsection {* Regla de la introducción de la doble negación *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 21 (p. 21) Demostrar la regla de introducción de la doble&lt;br /&gt;
  negación a partir de las reglas básicas.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_21_A: &amp;quot;F ⟹ ¬¬F&amp;quot;  &lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsubsection {* Regla de reducción al absurdo *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La regla de reducción al absurdo en Isabelle se corresponde con la&lt;br /&gt;
  regla clásica de contradicción &lt;br /&gt;
  · ccontr: (¬P ⟹ False) ⟹ P&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsubsection {* Ley del tercio excluso *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La ley del tercio excluso es &lt;br /&gt;
  · excluded_middle: ¬P ∨ P&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 22 (p. 23). Demostrar la ley del tercio excluso a partir de&lt;br /&gt;
  las reglas básicas.  &lt;br /&gt;
*}&lt;br /&gt;
  &lt;br /&gt;
lemma ejemplo_22: &amp;quot;F ∨ ¬F&amp;quot;&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo 23 (p. 24). Demostrar&lt;br /&gt;
     p ⟶ q ⊢ ¬p ∨ q&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_23: &amp;quot;p ⟶ q ⟹ ¬p ∨ q&amp;quot;&lt;br /&gt;
  apply (cut_tac P=&amp;quot;p&amp;quot; in excluded_middle)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
    prefer 2&lt;br /&gt;
   apply (drule mp)&lt;br /&gt;
    prefer 2&lt;br /&gt;
    apply (rule disjI2)&lt;br /&gt;
    apply assumption+&lt;br /&gt;
    done&lt;br /&gt;
  &lt;br /&gt;
subsection {* Demostraciones por contradicción *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo 24. Demostrar que &lt;br /&gt;
     ¬p, p ∨ q ⊢ q&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma ejemplo_24: &amp;quot;⟦¬p ; p ∨ q⟧ ⟹ q&amp;quot;  &lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule notE)&lt;br /&gt;
   apply assumption+&lt;br /&gt;
  done&lt;br /&gt;
   &lt;br /&gt;
end  &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bibliografía ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.phil.cmu.edu/~avigad/formal/FormalCheatSheet.pdf Isabelle / Proof General Cheat Sheet].&lt;br /&gt;
* [https://isabelle.in.tum.de/dist/Isabelle2018/doc/tutorial.pdf Isabelle/HOL: A Proof Assistant for Higher-Order Logic]. Cap. 5: The Rules of the Game.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_en_l%C3%B3gica_de_primer_orden_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=483</id>
		<title>Deducción natural en lógica de primer orden con Isabelle/HOL basada en tácticas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_en_l%C3%B3gica_de_primer_orden_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=483"/>
		<updated>2019-03-26T06:19:06Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
theory T4b&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Introducción&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Reglas de primer orden en Isabelle/HOL&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
thm spec [no_vars]&lt;br /&gt;
  (* da ∀x. P x ⟹ P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm allE [no_vars]&lt;br /&gt;
  (* da ⟦∀x. P x; P x ⟹ R⟧ ⟹ R *)  &lt;br /&gt;
  &lt;br /&gt;
thm allI [no_vars]&lt;br /&gt;
  (* da (⋀x. P x) ⟹ ∀x. P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm exI &lt;br /&gt;
  (* da ?P ?x ⟹ ∃x. ?P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm exE [no_vars]&lt;br /&gt;
  (* da ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q *)  &lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Ejemplos de demostraciones&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con spec y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;  &lt;br /&gt;
  apply (drule_tac x=a in spec)  (* da P a ⟹ ∃y. P y *)&lt;br /&gt;
  apply (rule_tac x=a in exI)    (* da P a ⟹ P a *)&lt;br /&gt;
  apply assumption               (* da  No subgoals!*)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
text {* Ejemplo con spec y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule exI)    (* da ∀x. P x ⟹ P ?x *)&lt;br /&gt;
  apply (erule spec)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con allE y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (erule allE)  (* da P ?x ⟹ ∃x. P x*)&lt;br /&gt;
  apply (erule exI)   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
 &lt;br /&gt;
text {* Ejemplo con erule_tac *}  &lt;br /&gt;
lemma &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  apply (rule allI)              (* da ⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ &lt;br /&gt;
                                           ⟹ Q z *)&lt;br /&gt;
  apply (erule_tac x=z in allE)  (* da ⋀z. ⟦∀y. P y; P z ⟶ Q z⟧ &lt;br /&gt;
                                           ⟹ Q z *)&lt;br /&gt;
  apply (erule_tac x=z in allE)  (* da ⋀z. ⟦P z ⟶ Q z; P z⟧ ⟹ Q z *)&lt;br /&gt;
  apply (erule impE)             (* da ⋀z. P z ⟹ P z&lt;br /&gt;
                                       ⋀z. ⟦P z; Q z⟧ ⟹ Q z *)&lt;br /&gt;
   apply assumption+             (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo sin erule_tac *}  &lt;br /&gt;
lemma &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  apply (rule allI)    (* da ⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z *)  &lt;br /&gt;
  apply (erule allE)   (* da ⋀z. ⟦∀y. P y; P (?x2 z) ⟶ Q (?x2 z)⟧ &lt;br /&gt;
                                 ⟹ Q z *)  &lt;br /&gt;
  apply (erule allE)   (* da ⋀z. ⟦P (?x2 z) ⟶ Q (?x2 z); P (?y4 z)⟧ &lt;br /&gt;
                                 ⟹ Q z *)  &lt;br /&gt;
  apply (erule mp)     (* da ⋀z. P (?y4 z) ⟹ P z *)  &lt;br /&gt;
  apply assumption     (* da No subgoals *)  &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* Ejemplo con exE *}    &lt;br /&gt;
lemma &amp;quot;(∃z. P z) ∧ Q ⟶ (∃y. P y ∧ Q)&amp;quot;&lt;br /&gt;
  apply (rule impI)              (* da (∃z. P z) ∧ Q ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (erule conjE)            (* da ⟦∃z. P z; Q⟧ ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (erule exE)              (* da ⋀z. ⟦Q; P z⟧ ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;z&amp;quot; in exI)  (* da ⋀z. ⟦Q; P z⟧ ⟹ P z ∧ Q *)&lt;br /&gt;
  apply (rule conjI)             (* da ⋀z. ⟦Q; P z⟧ ⟹ P z&lt;br /&gt;
                                       ⋀z. ⟦Q; P z⟧ ⟹ Q *)&lt;br /&gt;
   apply assumption+             (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Cálculo de secuentes de primer orden&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
lemma &amp;quot;A ⟹ ∀x. P x&amp;quot;&lt;br /&gt;
  apply (rule allI) (* da ⋀x. A ⟹ P x *)  &lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule allE)   (* da ⟦A; P ?x⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule_tac x=t in allE)   (* da ⟦A; P t⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (frule spec) (* da ⟦A; ∀x. P x; P ?x⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (frule_tac x=t in spec) (* da ⟦A; ∀x. P x; P t⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule exI) (* da A ⟹ P ?x *)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule_tac x=t in exI) (* da A ⟹ P t *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∃x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule exE)  (* da ⋀x. ⟦A; P x⟧ ⟹ Q *)&lt;br /&gt;
  oops  &lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Ejemplos del tema 6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Reglas del cuantificador universal *}&lt;br /&gt;
&lt;br /&gt;
lemma ej1: &amp;quot;⟦P(c); ∀x. (P(x) ⟶ ¬Q(x))⟧ ⟹ ¬Q(c)&amp;quot;&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej2: &amp;quot;⟦∀x. (P x ⟶ ¬(Q x)); ∀y. P y⟧ ⟹ ∀z. ¬(Q z)&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (erule allE)+&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Reglas del cuantificador existencial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma ej3: &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule exI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej4: &amp;quot;⟦∀x. P x ⟶ Q x; ∃y. P y⟧ ⟹ ∃z. Q z&amp;quot;&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (rule exI)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Demostraciones de equivalencias&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma ej5a: &amp;quot;¬(∀x. P x) ⟹ ∃y. ¬P y&amp;quot;&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
   apply (erule exI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej5b: &amp;quot;∃x. ¬P x ⟹ ¬(∀y. P y)&amp;quot;&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej5: &amp;quot;¬(∀x. P x) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej5a)&lt;br /&gt;
  apply (erule ej5b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6a: &amp;quot;∀x. P(x) ∧ Q(x) ⟹ (∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (rule allI)&lt;br /&gt;
   apply (erule allE)&lt;br /&gt;
   apply (erule conjE)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule conjE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6b: &amp;quot;(∀x. P x) ∧ (∀x. Q x) ⟹ ∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (drule conjunct1)&lt;br /&gt;
   apply (erule spec)&lt;br /&gt;
   apply (drule conjunct2)&lt;br /&gt;
  apply (erule spec)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6: &amp;quot;(∀x. P x ∧ Q x) ⟷ (∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej6a)&lt;br /&gt;
  apply (erule ej6b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7a: &amp;quot;(∃x. P x) ∨ (∃x. Q x) ⟹ ∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule exE)&lt;br /&gt;
   apply (rule exI)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (rule exI)&lt;br /&gt;
  apply (erule disjI2)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7b: &amp;quot;∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   apply (erule exI)&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  apply (erule exI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7: &amp;quot;(∃x. P x) ∨ (∃x. Q x) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej7a)&lt;br /&gt;
  apply (erule ej7b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8a: &amp;quot;∃x y. P x y ⟹ ∃y x. P x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+&lt;br /&gt;
  apply (rule exI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8b: &amp;quot;∃y x. P x y ⟹ ∃x y. P x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+&lt;br /&gt;
  apply (rule exI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej8: &amp;quot;(∃x y. P x y) ⟷ (∃y x. P x y)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej8a)&lt;br /&gt;
  apply (erule ej8b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bibliografía ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.phil.cmu.edu/~avigad/formal/FormalCheatSheet.pdf Isabelle / Proof General Cheat Sheet].&lt;br /&gt;
* [https://isabelle.in.tum.de/dist/Isabelle2018/doc/tutorial.pdf Isabelle/HOL: A Proof Assistant for Higher-Order Logic]. Cap. 5: The Rules of the Game.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_en_l%C3%B3gica_de_primer_orden_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=482</id>
		<title>Deducción natural en lógica de primer orden con Isabelle/HOL basada en tácticas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/LMF2019/index.php?title=Deducci%C3%B3n_natural_en_l%C3%B3gica_de_primer_orden_con_Isabelle/HOL_basada_en_t%C3%A1cticas&amp;diff=482"/>
		<updated>2019-03-26T06:17:36Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;isabelle&amp;quot;&amp;gt;&lt;br /&gt;
theory T4b&lt;br /&gt;
imports Main&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Introducción&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Reglas de primer orden en Isabelle/HOL&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
thm spec [no_vars]&lt;br /&gt;
  (* da ∀x. P x ⟹ P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm allE [no_vars]&lt;br /&gt;
  (* da ⟦∀x. P x; P x ⟹ R⟧ ⟹ R *)  &lt;br /&gt;
  &lt;br /&gt;
thm allI [no_vars]&lt;br /&gt;
  (* da (⋀x. P x) ⟹ ∀x. P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm exI &lt;br /&gt;
  (* da ?P ?x ⟹ ∃x. ?P x *)  &lt;br /&gt;
  &lt;br /&gt;
thm exE [no_vars]&lt;br /&gt;
  (* da ⟦∃x. P x; ⋀x. P x ⟹ Q⟧ ⟹ Q *)  &lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Ejemplos de demostraciones&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con spec y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;  &lt;br /&gt;
  apply (drule_tac x=a in spec)  (* da P a ⟹ ∃y. P y *)&lt;br /&gt;
  apply (rule_tac x=a in exI)    (* da P a ⟹ P a *)&lt;br /&gt;
  apply assumption               (* da  No subgoals!*)&lt;br /&gt;
  done&lt;br /&gt;
  &lt;br /&gt;
text {* Ejemplo con spec y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule exI)    (* da ∀x. P x ⟹ P ?x *)&lt;br /&gt;
  apply (erule spec)  (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo con allE y exI*}  &lt;br /&gt;
lemma &amp;quot;∀x. P x ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (erule allE)  (* da P ?x ⟹ ∃x. P x*)&lt;br /&gt;
  apply (erule exI)   (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
 &lt;br /&gt;
text {* Ejemplo con erule_tac *}  &lt;br /&gt;
lemma &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  apply (rule allI)              (* da ⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ &lt;br /&gt;
                                           ⟹ Q z *)&lt;br /&gt;
  apply (erule_tac x=z in allE)  (* da ⋀z. ⟦∀y. P y; P z ⟶ Q z⟧ &lt;br /&gt;
                                           ⟹ Q z *)&lt;br /&gt;
  apply (erule_tac x=z in allE)  (* da ⋀z. ⟦P z ⟶ Q z; P z⟧ ⟹ Q z *)&lt;br /&gt;
  apply (erule impE)             (* da ⋀z. P z ⟹ P z&lt;br /&gt;
                                       ⋀z. ⟦P z; Q z⟧ ⟹ Q z *)&lt;br /&gt;
   apply assumption+             (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
text {* Ejemplo sin erule_tac *}  &lt;br /&gt;
lemma &amp;quot;⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ ∀z. Q z&amp;quot;&lt;br /&gt;
  apply (rule allI)    (* da ⋀z. ⟦∀x. P x ⟶ Q x; ∀y. P y⟧ ⟹ Q z *)  &lt;br /&gt;
  apply (erule allE)   (* da ⋀z. ⟦∀y. P y; P (?x2 z) ⟶ Q (?x2 z)⟧ &lt;br /&gt;
                                 ⟹ Q z *)  &lt;br /&gt;
  apply (erule allE)   (* da ⋀z. ⟦P (?x2 z) ⟶ Q (?x2 z); P (?y4 z)⟧ &lt;br /&gt;
                                 ⟹ Q z *)  &lt;br /&gt;
  apply (erule mp)     (* da ⋀z. P (?y4 z) ⟹ P z *)  &lt;br /&gt;
  apply assumption     (* da No subgoals *)  &lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
text {* Ejemplo con exE *}    &lt;br /&gt;
lemma &amp;quot;(∃z. P z) ∧ Q ⟶ (∃y. P y ∧ Q)&amp;quot;&lt;br /&gt;
  apply (rule impI)              (* da (∃z. P z) ∧ Q ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (erule conjE)            (* da ⟦∃z. P z; Q⟧ ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (erule exE)              (* da ⋀z. ⟦Q; P z⟧ ⟹ ∃y. P y ∧ Q *)&lt;br /&gt;
  apply (rule_tac x=&amp;quot;z&amp;quot; in exI)  (* da ⋀z. ⟦Q; P z⟧ ⟹ P z ∧ Q *)&lt;br /&gt;
  apply (rule conjI)             (* da ⋀z. ⟦Q; P z⟧ ⟹ P z&lt;br /&gt;
                                       ⋀z. ⟦Q; P z⟧ ⟹ Q *)&lt;br /&gt;
   apply assumption+             (* da No subgoals! *)&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
subsection &amp;quot;Cálculo de secuentes de primer orden&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
lemma &amp;quot;A ⟹ ∀x. P x&amp;quot;&lt;br /&gt;
  apply (rule allI) (* da ⋀x. A ⟹ P x *)  &lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule allE)   (* da ⟦A; P ?x⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule_tac x=t in allE)   (* da ⟦A; P t⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (frule spec) (* da ⟦A; ∀x. P x; P ?x⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∀x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (frule_tac x=t in spec) (* da ⟦A; ∀x. P x; P t⟧ ⟹ Q *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule exI) (* da A ⟹ P ?x *)&lt;br /&gt;
  oops&lt;br /&gt;
    &lt;br /&gt;
lemma &amp;quot;A ⟹ ∃x. P x&amp;quot;&lt;br /&gt;
  apply (rule_tac x=t in exI) (* da A ⟹ P t *)&lt;br /&gt;
  oops&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦A; ∃x. P x⟧ ⟹ Q&amp;quot;&lt;br /&gt;
  apply (erule exE)  (* da ⋀x. ⟦A; P x⟧ ⟹ Q *)&lt;br /&gt;
  oops  &lt;br /&gt;
&lt;br /&gt;
section &amp;quot;Ejemplos del tema 6&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Reglas del cuantificador universal *}&lt;br /&gt;
&lt;br /&gt;
lemma ej1: &amp;quot;⟦P(c); ∀x. (P(x) ⟶ ¬Q(x))⟧ ⟹ ¬Q(c)&amp;quot;&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej2: &amp;quot;⟦∀x. (P x ⟶ ¬(Q x)); ∀y. P y⟧ ⟹ ∀z. ¬(Q z)&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (erule allE)+&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Reglas del cuantificador existencial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma ej3: &amp;quot;∀x. P x ⟹ ∃y. P y&amp;quot;&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule exI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej4: &amp;quot;⟦∀x. P x ⟶ Q x; ∃y. P y⟧ ⟹ ∃z. Q z&amp;quot;&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (rule exI)&lt;br /&gt;
  apply (erule mp)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
subsection &amp;quot;Demostraciones de equivalencias&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lemma ej5a: &amp;quot;¬(∀x. P x) ⟹ ∃y. ¬P y&amp;quot;&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (rule ccontr)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
   apply (erule exI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej5b: &amp;quot;∃x. ¬P x ⟹ ¬(∀y. P y)&amp;quot;&lt;br /&gt;
  apply (rule notI)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule notE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej5: &amp;quot;¬(∀x. P x) ⟷ (∃x. ¬P x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej5a)&lt;br /&gt;
  apply (erule ej5b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6a: &amp;quot;∀x. P(x) ∧ Q(x) ⟹ (∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (rule allI)&lt;br /&gt;
   apply (erule allE)&lt;br /&gt;
   apply (erule conjE)&lt;br /&gt;
   apply assumption&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (erule allE)&lt;br /&gt;
  apply (erule conjE)&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6b: &amp;quot;(∀x. P x) ∧ (∀x. Q x) ⟹ ∀x. P x ∧ Q x&amp;quot;&lt;br /&gt;
  apply (rule allI)&lt;br /&gt;
  apply (rule conjI)&lt;br /&gt;
   apply (drule conjunct1)&lt;br /&gt;
   apply (erule spec)&lt;br /&gt;
   apply (drule conjunct2)&lt;br /&gt;
  apply (erule spec)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej6: &amp;quot;(∀x. P x ∧ Q x) ⟷ (∀x. P x) ∧ (∀x. Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej6a)&lt;br /&gt;
  apply (erule ej6b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7a: &amp;quot;(∃x. P x) ∨ (∃x. Q x) ⟹ ∃x. P x ∨ Q x&amp;quot;&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (erule exE)&lt;br /&gt;
   apply (rule exI)&lt;br /&gt;
   apply (erule disjI1)&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (rule exI)&lt;br /&gt;
  apply (erule disjI2)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7b: &amp;quot;∃x. P x ∨ Q x ⟹ (∃x. P x) ∨ (∃x. Q x)&amp;quot;&lt;br /&gt;
  apply (erule exE)&lt;br /&gt;
  apply (erule disjE)&lt;br /&gt;
   apply (rule disjI1)&lt;br /&gt;
   apply (erule exI)&lt;br /&gt;
  apply (rule disjI2)&lt;br /&gt;
  apply (erule exI)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej7: &amp;quot;(∃x. P x) ∨ (∃x. Q x) ⟷ (∃x. P x ∨ Q x)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej7a)&lt;br /&gt;
  apply (erule ej7b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8a: &amp;quot;∃x y. P x y ⟹ ∃y x. P x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+&lt;br /&gt;
  apply (rule exI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
lemma ej8b: &amp;quot;∃y x. P x y ⟹ ∃x y. P x y&amp;quot;&lt;br /&gt;
  apply (erule exE)+&lt;br /&gt;
  apply (rule exI)+&lt;br /&gt;
  apply assumption&lt;br /&gt;
  done&lt;br /&gt;
&lt;br /&gt;
lemma ej8: &amp;quot;(∃x y. P x y) ⟷ (∃y x. P x y)&amp;quot;&lt;br /&gt;
  apply (rule iffI)&lt;br /&gt;
   apply (erule ej8a)&lt;br /&gt;
  apply (erule ej8b)&lt;br /&gt;
  done&lt;br /&gt;
    &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bibliografía ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.phil.cmu.edu/~avigad/formal/FormalCheatSheet.pdf Isabelle / Proof General Cheat Sheet].&lt;br /&gt;
* [https://isabelle.in.tum.de/dist/Isabelle2018/doc/tutorial.pdf Isabelle/HOL: A Proof Assistant for Higher-Order Logic].&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
</feed>