<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
	<id>https://www.glc.us.es/~jalonso/RA2010/index.php?action=history&amp;feed=atom&amp;title=Miscel%C3%A1neas</id>
	<title>Misceláneas - Historial de revisiones</title>
	<link rel="self" type="application/atom+xml" href="https://www.glc.us.es/~jalonso/RA2010/index.php?action=history&amp;feed=atom&amp;title=Miscel%C3%A1neas"/>
	<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/RA2010/index.php?title=Miscel%C3%A1neas&amp;action=history"/>
	<updated>2026-09-20T02:14:26Z</updated>
	<subtitle>Historial de revisiones para esta página en el wiki</subtitle>
	<generator>MediaWiki 1.31.14</generator>
	<entry>
		<id>https://www.glc.us.es/~jalonso/RA2010/index.php?title=Miscel%C3%A1neas&amp;diff=334&amp;oldid=prev</id>
		<title>Jalonso: Texto reemplazado: «&quot;isar&quot;» por «&quot;isabelle&quot;»</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/RA2010/index.php?title=Miscel%C3%A1neas&amp;diff=334&amp;oldid=prev"/>
		<updated>2021-07-24T15:27:25Z</updated>

		<summary type="html">&lt;p&gt;Texto reemplazado: «&amp;quot;isar&amp;quot;» por «&amp;quot;isabelle&amp;quot;»&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;es&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Revisión anterior&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Revisión del 15:27 24 jul 2021&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot; &gt;Línea 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Línea 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&#039;diff-marker&#039;&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;isar&lt;/del&gt;&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&#039;diff-marker&#039;&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;isabelle&lt;/ins&gt;&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&#039;diff-marker&#039;&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;theory Tema8&lt;/div&gt;&lt;/td&gt;&lt;td class=&#039;diff-marker&#039;&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;theory Tema8&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&#039;diff-marker&#039;&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;imports Main Efficient_Nat&lt;/div&gt;&lt;/td&gt;&lt;td class=&#039;diff-marker&#039;&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;imports Main Efficient_Nat&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/RA2010/index.php?title=Miscel%C3%A1neas&amp;diff=182&amp;oldid=prev</id>
		<title>Jalonso: Página creada con &#039;&lt;source lang=&quot;isar&quot;&gt; theory Tema8 imports Main Efficient_Nat begin  header {* Misceláneas *}  text {*   Contenido:   * Definición del algoritmo de Huffman   * Definiciones ind...&#039;</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/RA2010/index.php?title=Miscel%C3%A1neas&amp;diff=182&amp;oldid=prev"/>
		<updated>2011-02-21T07:49:56Z</updated>

		<summary type="html">&lt;p&gt;Página creada con &amp;#039;&amp;lt;source lang=&amp;quot;isar&amp;quot;&amp;gt; theory Tema8 imports Main Efficient_Nat begin  header {* Misceláneas *}  text {*   Contenido:   * Definición del algoritmo de Huffman   * Definiciones ind...&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Página nueva&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;isar&amp;quot;&amp;gt;&lt;br /&gt;
theory Tema8&lt;br /&gt;
imports Main Efficient_Nat&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
header {* Misceláneas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Contenido:&lt;br /&gt;
  * Definición del algoritmo de Huffman&lt;br /&gt;
  * Definiciones inductivas&lt;br /&gt;
    * Demostraciones por introducción&lt;br /&gt;
    * Demostraciones por inducción sobre conjuntos inductivos&lt;br /&gt;
  * Clases&lt;br /&gt;
    * Subclase&lt;br /&gt;
    * Instanciación de clases&lt;br /&gt;
  * Ámbitos (&amp;quot;Locales&amp;quot;)&lt;br /&gt;
  * Demostraciones estructuradas: inducción y encadenamiento&lt;br /&gt;
  * Un ejemplo elemental de álgebra&lt;br /&gt;
    * Definición de clases&lt;br /&gt;
    * Instanciación de clases&lt;br /&gt;
    * Instancias recursivas&lt;br /&gt;
    * Subclases&lt;br /&gt;
  * Las clases de tipos como ámbitos&lt;br /&gt;
    * Razonamiento abstracto&lt;br /&gt;
    * Definiciones derivadas&lt;br /&gt;
    * Analogía entre clases y functores&lt;br /&gt;
    * Relaciones de subclase adicionales&lt;br /&gt;
  * Otras cuestiones&lt;br /&gt;
    * Clases de tipos y generación de código&lt;br /&gt;
    * Inspección del universo de las clases de tipos&lt;br /&gt;
  * Sledgehammer&lt;br /&gt;
  * Refute&lt;br /&gt;
    * Refutaciones en lógica proposicional&lt;br /&gt;
      * Refutaciones en lógica de predicados&lt;br /&gt;
      * Refutaciones con funciones e igualdad&lt;br /&gt;
    * Ejemplos con listas&lt;br /&gt;
  * Nitpick&lt;br /&gt;
    * Refutación proposicional&lt;br /&gt;
    * Skolemizaciónn&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Definición del algoritmo de Huffman *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de definición de tipo de datos recursivo: árboles binarios.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
datatype &amp;#039;a arbol = Hoja nat &amp;#039;a | Nodo nat &amp;quot;(&amp;#039;a arbol)&amp;quot; &amp;quot;(&amp;#039;a arbol)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Ejemplo de definición primitiva recursiva sobre un tipo definido:&lt;br /&gt;
  Definición del valor de un árbol. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
primrec &amp;quot;valor&amp;quot; where&lt;br /&gt;
  &amp;quot;valor (Hoja n _) = n&amp;quot; &lt;br /&gt;
| &amp;quot;valor (Nodo n _ _) = n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de definición no recursiva: Mezcla de dos árboles.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition &amp;quot;mezcla t1 t2 = Nodo (valor t1 + valor t2) t1 t2&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Definición de la inserción de un árbol en un bosque.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun ins where&lt;br /&gt;
  &amp;quot;ins u (t#ts) = (if valor u ≤ valor t then u # t # ts else t # ins u ts)&amp;quot; &lt;br /&gt;
| &amp;quot;ins u [] = [u]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Lema para usar en las demostraciones de terminación. En particular, en&lt;br /&gt;
  la definición de creaArbol. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma size_ins[termination_simp]: &amp;quot;size(ins u ts) = size ts + 1&amp;quot;&lt;br /&gt;
by (induct ts) simp_all&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Creación de árboles a partir de listas &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
fun creaArbol where&lt;br /&gt;
  &amp;quot;creaArbol(t1#t2#ts) = creaArbol(ins (mezcla t1 t2) ts)&amp;quot; &lt;br /&gt;
| &amp;quot;creaArbol[t] = t&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de formas normales: creación de árboles de Huffman.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
value&lt;br /&gt;
  &amp;quot;creaArbol[Hoja 3 a, Hoja 6 b, Hoja 12 c, Hoja 24 d]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  El árbol creado es&lt;br /&gt;
  &amp;quot;Nodo 45 (Nodo 21 (Nodo 9 (Hoja 3 a) (Hoja 6 b)) (Hoja 12 c)) (Hoja 24 d)&amp;quot; *}&lt;br /&gt;
&lt;br /&gt;
value&lt;br /&gt;
  &amp;quot;creaArbol[Hoja 24 d, Hoja 6 b, Hoja 12 c, Hoja 3 a]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  El árbol creado es&lt;br /&gt;
  &amp;quot;Nodo 45 (Nodo 15 (Hoja 12 c) (Hoja 3 a)) (Nodo 30 (Hoja 24 d) (Hoja 6 b))&amp;quot;&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Definiciones inductivas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En esta sección vamos a trabajar con una gramática cuyo alfabeto consta de&lt;br /&gt;
  dos símbolos: A y B. En primer lugar, se define el alfabeto (alfa)&lt;br /&gt;
  como un tipo con dos elementos. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
datatype alfa = A | B&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se define la gramática S como el conjunto de las listas de elementos del&lt;br /&gt;
  alfabeto generadas mediante las siguientes reglas:&lt;br /&gt;
  · La lista vacía está en S,&lt;br /&gt;
  · Si w está en S, entonces AwB también lo está.&lt;br /&gt;
  · Si v y w están en S, entonces vw también lo está. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
inductive_set S :: &amp;quot;alfa list set&amp;quot; where&lt;br /&gt;
  S1: &amp;quot;[] ∈ S&amp;quot; &lt;br /&gt;
| S2: &amp;quot;w ∈ S ⟹ [A] @ w @ [B] ∈ S&amp;quot; &lt;br /&gt;
| S3: &amp;quot;v ∈ S ⟹ w ∈ S ⟹ v @ w ∈ S&amp;quot;&lt;br /&gt;
&lt;br /&gt;
subsection {* Demostraciones por introducción *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    La lista [A, B] está en S.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;[A, B] ∈ S&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;[] ∈ S&amp;quot; by (rule S1)&lt;br /&gt;
  hence &amp;quot;[A] @ [] @ [B] ∈ S&amp;quot; by (rule S2)&lt;br /&gt;
  thus ?thesis by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
subsection {* Demostraciones por inducción sobre conjuntos inductivos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ninguna palabra de la gramática empieze por B.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;w ∈ S ⟹ ¬ (∃v. w = B # v)&amp;quot;&lt;br /&gt;
proof (induct set:S)&lt;br /&gt;
  case S1&lt;br /&gt;
  thus ?case by simp&lt;br /&gt;
next&lt;br /&gt;
  case S2&lt;br /&gt;
  thus ?case by simp&lt;br /&gt;
next&lt;br /&gt;
  case S3&lt;br /&gt;
  thus ?case (* sledgehammer *) by (simp add: append_eq_Cons_conv)  &lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* 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 refl&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;
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;
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;
subsection {* Instanciación de clases *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El producto de dos órdenes es un orden.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
instantiation prod :: (orden, orden) orden&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
inductive menor_ig_prod :: &amp;quot;&amp;#039;a × &amp;#039;b ⇒ &amp;#039;a × &amp;#039;b ⇒ bool&amp;quot; where&lt;br /&gt;
  menor_ig_fst: &amp;quot;x ≺ v ⟹ (x, y) ≼ (v, w)&amp;quot; &lt;br /&gt;
| menor_ig_snd: &amp;quot;x = v ⟹ y ≼ w ⟹ (x, y) ≼ (v, w)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
instance&lt;br /&gt;
proof&lt;br /&gt;
  fix p :: &amp;quot;&amp;#039;a × &amp;#039;b&amp;quot;&lt;br /&gt;
  show &amp;quot;p ≼ p&amp;quot; by (cases p) (auto intro!: menor_ig_snd refl)&lt;br /&gt;
next&lt;br /&gt;
  fix p q r :: &amp;quot;&amp;#039;a × &amp;#039;b&amp;quot;&lt;br /&gt;
  assume &amp;quot;p ≼ r&amp;quot; and &amp;quot;r ≼ q&amp;quot;&lt;br /&gt;
  then show &amp;quot;p ≼ q&amp;quot;&lt;br /&gt;
    by (induct p r rule:menor_ig_prod.induct)&lt;br /&gt;
       (auto elim!:menor_ig_prod.cases &lt;br /&gt;
             intro:menor_ig_fst menor_ig_snd trans menor_trans)&lt;br /&gt;
next&lt;br /&gt;
  fix p q :: &amp;quot;&amp;#039;a × &amp;#039;b&amp;quot;&lt;br /&gt;
  assume &amp;quot;p ≼ q&amp;quot; and &amp;quot;q ≼ p&amp;quot;&lt;br /&gt;
  then show &amp;quot;p = q&amp;quot;&lt;br /&gt;
    by (induct p q rule:menor_ig_prod.induct)&lt;br /&gt;
       (auto elim!:menor_ig_prod.cases &lt;br /&gt;
             elim:asimetrica &lt;br /&gt;
             intro:antisim &lt;br /&gt;
             simp:irrefl)&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
section {* Ámbitos (&amp;quot;Locales&amp;quot;) *}&lt;br /&gt;
&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;op ⟶&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;
thm dvd.order_trans&lt;br /&gt;
thm dvd.less_le_trans&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;op dvd :: nat ⇒ nat ⇒ bool&amp;quot;&lt;br /&gt;
proof qed (auto intro: dvd_refl dvd_trans dvd_antisym)&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;⊑\&amp;lt;^isub&amp;gt;1&amp;quot; 50) and le2 (infix &amp;quot;⊑\&amp;lt;^isub&amp;gt;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 ⊑\&amp;lt;^isub&amp;gt;1 y ⟹ f(x) ⊑\&amp;lt;^isub&amp;gt;2 f(y)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Si f es monótona, x ⊑\&amp;lt;^isub&amp;gt;1 y e y ⊑\&amp;lt;^isub&amp;gt;1 z, entonces f(x) ⊑\&amp;lt;^isub&amp;gt;2 f(z).&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma (in Mono) mono_trans: &lt;br /&gt;
  assumes &amp;quot;x ⊑\&amp;lt;^isub&amp;gt;1 y&amp;quot; and &amp;quot;y ⊑\&amp;lt;^isub&amp;gt;1 z&amp;quot; &lt;br /&gt;
  shows &amp;quot;f(x) ⊑\&amp;lt;^isub&amp;gt;2 f(z)&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  have &amp;quot;x ⊑\&amp;lt;^isub&amp;gt;1 z&amp;quot; using assms and le1.trans by blast&lt;br /&gt;
  thus &amp;quot;f(x) ⊑\&amp;lt;^isub&amp;gt;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 begin thm mono_trans 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 ⟹ 2 dvd x ⟶ 2 dvd y&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
interpretation Mono &amp;quot;op dvd&amp;quot; &amp;quot;op ⟶&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 ⟹ 2 dvd x ⟶ 2 dvd y&amp;quot;&lt;br /&gt;
    proof &lt;br /&gt;
      assume &amp;quot;x dvd y&amp;quot; and &amp;quot;2 dvd x&amp;quot;&lt;br /&gt;
      thus &amp;quot;2 dvd y&amp;quot; using dvd.order_trans by blast&lt;br /&gt;
    qed&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Demostraciones estructuradas: inducción y encadenamiento *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
    El siguiente ejemplo se encuentra en Wenzel2006 pp. 3--5 y el código&lt;br /&gt;
    en Isar_Example/Puzzle.thy. Una demostración más actualizada se&lt;br /&gt;
    encuentra en Nipkow2009 p.1 basada en la de Tao2006 pp. 34--36. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
theorem identity1: &lt;br /&gt;
  fixes f :: &amp;quot;nat ⇒ nat&amp;quot;&lt;br /&gt;
  assumes fff: &amp;quot;⋀n. f(f(n)) &amp;lt; f(Suc(n))&amp;quot;&lt;br /&gt;
  shows &amp;quot;f(n) = n&amp;quot;&lt;br /&gt;
proof -&lt;br /&gt;
  { fix m n have key: &amp;quot;n ≤ m ⟹ n ≤ f(m)&amp;quot;&lt;br /&gt;
    proof(induct n arbitrary: m)&lt;br /&gt;
      case 0 show ?case by simp&lt;br /&gt;
    next&lt;br /&gt;
      case (Suc n)&lt;br /&gt;
      have HI1: &amp;quot;⋀k. n ≤ k ⟹ n ≤ f k&amp;quot; using Suc by simp&lt;br /&gt;
      have HI2: &amp;quot;Suc n ≤ m&amp;quot; using Suc by simp&lt;br /&gt;
      hence &amp;quot;m ≠ 0&amp;quot; by simp&lt;br /&gt;
      then obtain k where [simp]: &amp;quot;m = Suc k&amp;quot; by (metis not0_implies_Suc)&lt;br /&gt;
      have &amp;quot;n ≤ k&amp;quot; using HI2 by simp&lt;br /&gt;
      have &amp;quot;n ≤ f(k)&amp;quot; using Suc by simp&lt;br /&gt;
      hence &amp;quot;n ≤ f(f(k))&amp;quot; using Suc by simp&lt;br /&gt;
      also have &amp;quot;… &amp;lt; f(m)&amp;quot; using fff by simp&lt;br /&gt;
      finally show ?case by simp&lt;br /&gt;
    qed }&lt;br /&gt;
  hence &amp;quot;⋀n. n ≤ f(n)&amp;quot; by simp&lt;br /&gt;
  hence &amp;quot;⋀n. f(n) &amp;lt; f(Suc n)&amp;quot; by(metis fff order_le_less_trans)&lt;br /&gt;
  hence &amp;quot;f(n) &amp;lt; n+1&amp;quot; by (metis fff lift_Suc_mono_less_iff[of f] Suc_eq_plus1)&lt;br /&gt;
  with `n ≤ f(n)` show &amp;quot;f n = n&amp;quot; by arith&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
section {* Un ejemplo elemental de álgebra *}&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;
  thus &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;1&amp;quot;) &lt;br /&gt;
  assumes neutroI: &amp;quot;1 ⊗ 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;1 = (0::nat)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
definition &lt;br /&gt;
  neutro_int_def : &amp;quot;1 = (0::int)&amp;quot; &lt;br /&gt;
&lt;br /&gt;
instance proof &lt;br /&gt;
  fix n :: nat &lt;br /&gt;
  show &amp;quot;1 ⊗ 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;1 ⊗ 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;1 = (1, 1)&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;1 ⊗ 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 ⊗ 1 = 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 ⊗ 1 = 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 ⊗ 1 = 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 ⊗ 1 = 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 grupo = monoideI + &lt;br /&gt;
  fixes inverso :: &amp;quot;&amp;#039;a ⇒ &amp;#039;a&amp;quot; (&amp;quot;(_⁻)&amp;quot; [1000] 999)&lt;br /&gt;
  assumes inversoI: &amp;quot;x⁻ ⊗ x = 1&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 :: grupo &lt;br /&gt;
begin &lt;br /&gt;
&lt;br /&gt;
definition&lt;br /&gt;
  inverso_int_def: &amp;quot;i⁻ = -(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⁻ ⊗ i = 1&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;
section {* Las clases de tipos como ámbitos *}&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 grupo) 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⁻ ⊗ (x ⊗ y) = x⁻ ⊗ (x ⊗ z)&amp;quot; by simp &lt;br /&gt;
  hence &amp;quot;(x⁻ ⊗ x) ⊗ y = (x⁻ ⊗ x) ⊗ z&amp;quot; using asoc by simp &lt;br /&gt;
  thus &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;
  thus &amp;quot;x ⊗ y = x ⊗ z&amp;quot; by simp&lt;br /&gt;
qed&lt;br /&gt;
&lt;br /&gt;
thm Tema8.grupo.cancelativa_izq&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se genera el teorema Tema8b.grupo.cancelativa_izq&lt;br /&gt;
     class.grupo ?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;
primrec (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 = 1&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 qed auto&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;
primrec 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; where &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 grupo) monoide &lt;br /&gt;
proof &lt;br /&gt;
  fix x &lt;br /&gt;
  have &amp;quot;x⁻ ⊗ (x ⊗ 1) = x⁻ ⊗ (x ⊗ (x⁻ ⊗ x))&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;... = (x⁻ ⊗ x) ⊗ (x⁻ ⊗ x)&amp;quot; using asoc [symmetric] by simp&lt;br /&gt;
  also have &amp;quot;... = 1 ⊗ (x⁻ ⊗ x)&amp;quot; using inversoI by simp&lt;br /&gt;
  also have &amp;quot;... = x⁻ ⊗ x&amp;quot; using neutroI by simp&lt;br /&gt;
  finally have &amp;quot;x⁻ ⊗ (x ⊗ 1) = x⁻ ⊗ x&amp;quot; . &lt;br /&gt;
  thus &amp;quot;x ⊗ 1 = 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 grupo) 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)⁻)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
section {* Otras cuestiones *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Clases de tipos y generación de código *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo para evaluar.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
definition ejemplo :: int where &lt;br /&gt;
  &amp;quot;ejemplo = potencia_entera 10 (-2)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Al evaluar la siguiente expresión se obtiene como valor -20.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
value &amp;quot;ejemplo&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de generación de código Haskell.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
export_code ejemplo&lt;br /&gt;
  in Haskell file &amp;quot;codigoHaskell/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El código Haskell se exporta en el fichero codigoHaskell/Tema8b.hs&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Inspección del universo de las clases de tipos *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se puede obtener la lista de las clases con print_classes. Por&lt;br /&gt;
  ejemplo, evaluando la siguiente expresión se obtiene&lt;br /&gt;
      class semigrupo:&lt;br /&gt;
        supersort: type&lt;br /&gt;
        parameters:&lt;br /&gt;
          mult :: &amp;#039;a ⇒ &amp;#039;a ⇒ &amp;#039;a&lt;br /&gt;
        instances:&lt;br /&gt;
          int :: semigrupo, nat :: semigrupo,&lt;br /&gt;
            prod :: (semigrupo, semigrupo) semigrupo&lt;br /&gt;
      &lt;br /&gt;
      class monoideI:&lt;br /&gt;
        supersort: semigrupo&lt;br /&gt;
        parameters:&lt;br /&gt;
          neutro :: &amp;#039;a&lt;br /&gt;
        instances:&lt;br /&gt;
          int :: monoideI, nat :: monoideI, prod :: (monoideI, monoideI) monoideI&lt;br /&gt;
      &lt;br /&gt;
      class monoide:&lt;br /&gt;
        supersort: monoideI&lt;br /&gt;
        instances: int :: monoide, nat :: monoide, prod :: (monoide, monoide) monoide&lt;br /&gt;
      &lt;br /&gt;
      class grupo:&lt;br /&gt;
        supersort: monoide&lt;br /&gt;
        parameters:&lt;br /&gt;
          inverso :: &amp;#039;a ⇒ &amp;#039;a&lt;br /&gt;
        instances: int :: grupo&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
print_classes&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se puede obtener el grafo de las clases con class_deps.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
class_deps&lt;br /&gt;
&lt;br /&gt;
section {* Sledgehammer *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Demostración con Sledgehammer de la paradoja del bebedor: ``hay una persona&lt;br /&gt;
  en el bar, tal que si dicha persona bebe todos beben&amp;#039;&amp;#039;.&lt;br /&gt;
*}&lt;br /&gt;
lemma &amp;quot;∃x. P x ⟶ (∀y. P y)&amp;quot;&lt;br /&gt;
by metis&lt;br /&gt;
&lt;br /&gt;
section {* Refute *}&lt;br /&gt;
&lt;br /&gt;
subsection {* Refutaciones en lógica proposicional *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de refutación proposicional.&lt;br /&gt;
*}&lt;br /&gt;
lemma &amp;quot;P ⟷ Q&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El resultado obtenido es&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      empty universe (no type variables in term)&lt;br /&gt;
      Q: True&lt;br /&gt;
      P: False&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsubsection {* Refutaciones en lógica de predicados *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de refutación en lógica de primer orden.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(∃x. P x) ⟶ (∀x. P x)&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El resultado obtenido es&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a: 2&lt;br /&gt;
      P: {(a0, True), (a1, False)}&lt;br /&gt;
  que da un contraejemplo cuyo universo es {a₀, a₁} y sólo se verifica&lt;br /&gt;
  en a₀. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Ejemplo de refutación en lógica de primer orden con relaciones binarias.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(∀x. ∃y. P x y) ⟶ (∃y. ∀x. P x y)&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El resultado obtenido es&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a: 2, &amp;#039;b: 2&lt;br /&gt;
      P: {(a0, {(b0, True), (b1, False)}), (a1, {(b0, False), (b1, True)})}&lt;br /&gt;
  que da un contraejemplo cuyo universo es {a₀, a₁, b₀, b₁} y P sólo se&lt;br /&gt;
  verifica en {(a₀,b₁),(a₁,b₀)}. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Conjetura: Toda relación reflexiva y simétrica es transitiva. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;⟦ ∀x. P x x; ∀x y. P x y ⟶ P y x ⟧ ⟹ P x y ⟶ P y z ⟶ P x z&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  El resultado obtenido es&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a: 3&lt;br /&gt;
      z: a0&lt;br /&gt;
      y: a2&lt;br /&gt;
      x: a1&lt;br /&gt;
      P: {(a0, {(a0, True), (a1, False), (a2, True)}), &lt;br /&gt;
                (a1, {(a0, False), (a1, True), (a2, True)}), &lt;br /&gt;
                (a2, {(a0, True), (a1, True), (a2, True)})}&lt;br /&gt;
  que da un contraejemplo cuyo universo es {a₀, a₁, a₂} y P sólo se&lt;br /&gt;
  verifica en &lt;br /&gt;
     {(a₀,a₀),(a₀,a₁),(a₀,a₂),(a₁,a₀),(a₁,a₁),(a₂,a₀),(a₂,a₂)}.&lt;br /&gt;
  Entonces P es reflexiva y simétrica, pero no es transitiva porque &lt;br /&gt;
  se tiene que P(a₂,a₀) y P(a₀,a₁) y no se verifica P(a₂,a₁).&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsubsection {* Refutaciones con funciones e igualdad *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  En los siguientes ejemplos se consideran símbolos de función y el de&lt;br /&gt;
  igualdad.&lt;br /&gt;
&lt;br /&gt;
  Ejemplo de fallo en la refutación de la paradoja del mentiroso.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;∃x. f x = g x ⟶ f = g&amp;quot;&lt;br /&gt;
refute [maxsize=4]&lt;br /&gt;
apply (auto simp add: ext)&lt;br /&gt;
done &lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Refutación de una versión incorrecta de la paradoja del bebedor.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(∃x. f x = g x) ⟶ f = g&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se obtiene&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a: 2, &amp;#039;b: 2&lt;br /&gt;
      g: {(a0, b1), (a1, b1)}&lt;br /&gt;
      f: {(a0, b0), (a1, b1)}&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
    La composición de funciones es conmutativa.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;f (g x) = g (f x)&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se obtiene&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a: 2&lt;br /&gt;
      x: a0&lt;br /&gt;
      g: {(a0, a1), (a1, a0)}&lt;br /&gt;
      f: {(a0, a1), (a1, a1)}&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Toda función suprayectiva tiene inversa.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(∀y. ∃x. y = f x) ⟶ (∃g. ∀x. g (f x) = x)&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se obtiene&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a: 1, &amp;#039;b: 2&lt;br /&gt;
      f: {(b0, a0), (b1, a0)}&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Toda función que tiene inversa es suprayectiva.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;(∃g. ∀x. g (f x) = x) ⟶ (∀y. ∃x. y = f x)&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se obtiene&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;b: 1, &amp;#039;a: 2&lt;br /&gt;
      f: {(b0, a1)}&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Ejemplos con listas *}&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  La concatenación de listas es conmutativa.&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;xs @ ys = ys @ xs&amp;quot;&lt;br /&gt;
refute&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {*&lt;br /&gt;
  Se obtiene&lt;br /&gt;
      *** Model found: ***&lt;br /&gt;
      Size of types: &amp;#039;a list: 3, &amp;#039;a: 2&lt;br /&gt;
      ys: [a0]&lt;br /&gt;
      xs: [a1]&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
section {* Nitpick *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Notas:&lt;br /&gt;
  · Nitpick es un generador de contraejemplos.&lt;br /&gt;
  · Los ejemplos están elegidos de Nitpick_Examples.thy. &lt;br /&gt;
  · Para los ejemplos de Nitpick se deshabilita el QuicCheck automático.&lt;br /&gt;
  · Nitpick va a usar MiniSATJNI con una hebra. &lt;br /&gt;
*} &lt;br /&gt;
nitpick_params [sat_solver = MiniSat_JNI, max_threads = 1]&lt;br /&gt;
&lt;br /&gt;
subsection {* Refutación proposicional *}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;P ⟷ Q&amp;quot;&lt;br /&gt;
nitpick&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Se obtiene&lt;br /&gt;
      Nitpick found a counterexample:&lt;br /&gt;
        Free variables:&lt;br /&gt;
          P = True&lt;br /&gt;
          Q = False&lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
subsection {* Skolemizaciónn *}&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Conjetura: Las funciones que tienen inversa son suprayectivas. &lt;br /&gt;
*}&lt;br /&gt;
&lt;br /&gt;
lemma &amp;quot;∃g. ∀x. g (f x) = x ⟹ ∀y. ∃x. y = f x&amp;quot;&lt;br /&gt;
nitpick&lt;br /&gt;
oops&lt;br /&gt;
&lt;br /&gt;
text {* &lt;br /&gt;
  Se obtiene &lt;br /&gt;
      Nitpick found a counterexample for card &amp;#039;a = 2 and card &amp;#039;b = 1:&lt;br /&gt;
      &lt;br /&gt;
        Free variable:&lt;br /&gt;
          f = (λx. _)(b\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt; := a\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt;)&lt;br /&gt;
        Skolem constants:&lt;br /&gt;
          g = (λx. _)(a\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt; := b\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt;, a\&amp;lt;^bsub&amp;gt;2\&amp;lt;^esub&amp;gt; := b\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt;)&lt;br /&gt;
          y = a\&amp;lt;^bsub&amp;gt;2\&amp;lt;^esub&amp;gt;&lt;br /&gt;
  Significa que que Nitpick ha encontrado un contraejemplo donde&lt;br /&gt;
  · A={a\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt;,a\&amp;lt;^bsub&amp;gt;2\&amp;lt;^esub&amp;gt;}&lt;br /&gt;
  · B={b\&amp;lt;^bsub&amp;gt;1\&amp;lt;^esub&amp;gt;}&lt;br /&gt;
  · f: B → A tal que f(b\&amp;lt;^sub&amp;gt;1)=a\&amp;lt;^sub&amp;gt;1&lt;br /&gt;
  Entonces, f tiene inversa (la función g: A → B tal que g(a\&amp;lt;^sub&amp;gt;1)=b\&amp;lt;^sub&amp;gt;1 y&lt;br /&gt;
  g(a\&amp;lt;^sub&amp;gt;2)=b\&amp;lt;^sub&amp;gt;1), pero no es suprayectiva (el elemento a\&amp;lt;^sub&amp;gt;2 no tiene antiimagen).&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>
</feed>