<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
	<id>https://www.glc.us.es/~jalonso/SLC2018/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jalonso</id>
	<title>Seminario de Lógica Computacional (2018) - Contribuciones del usuario [es]</title>
	<link rel="self" type="application/atom+xml" href="https://www.glc.us.es/~jalonso/SLC2018/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jalonso"/>
	<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php/Especial:Contribuciones/Jalonso"/>
	<updated>2026-07-18T07:36:59Z</updated>
	<subtitle>Contribuciones del usuario</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_5&amp;diff=123</id>
		<title>Tema 5</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_5&amp;diff=123"/>
		<updated>2018-07-15T11:00:11Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;coq&amp;quot;&amp;gt;&lt;br /&gt;
(* T5: Tácticas básicas *)&lt;br /&gt;
&lt;br /&gt;
Require Export T4_PolimorfismoyOS.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § La táctica apply&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración donde el objetivo coincide con alguna&lt;br /&gt;
   hipótesis. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* Demostración sin apply *)&lt;br /&gt;
Theorem silly1 : forall (n m o p : nat),&lt;br /&gt;
    n = m  -&amp;gt;&lt;br /&gt;
    [n;o] = [n;p] -&amp;gt;&lt;br /&gt;
    [n;o] = [m;p].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p eq1 eq2.&lt;br /&gt;
  (* [n; o] = [m; p] *)&lt;br /&gt;
  rewrite &amp;lt;- eq1.&lt;br /&gt;
  (* [n; o] = [n; p] *)&lt;br /&gt;
  rewrite eq2.&lt;br /&gt;
  (* [n; p] = [n; p] *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Demostración con apply *)&lt;br /&gt;
Theorem silly1&amp;#039; : forall (n m o p : nat),&lt;br /&gt;
    n = m  -&amp;gt;&lt;br /&gt;
    [n;o] = [n;p] -&amp;gt;&lt;br /&gt;
    [n;o] = [m;p].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p eq1 eq2.&lt;br /&gt;
  (* [n; o] = [m; p] *)&lt;br /&gt;
  rewrite &amp;lt;- eq1.&lt;br /&gt;
  (* [n; o] = [n; p] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de aplicación de apply con hipótesis condicionales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly2 : forall (n m o p : nat),&lt;br /&gt;
    n = m  -&amp;gt;&lt;br /&gt;
    (forall (q r : nat), q = r -&amp;gt; [q;o] = [r;p]) -&amp;gt;&lt;br /&gt;
    [n;o] = [m;p].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p eq1 eq2.&lt;br /&gt;
  (* [n; o] = [m; p] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
  (* n = m *)&lt;br /&gt;
  apply eq1.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de aplicación de apply con hipótesis condicionales y&lt;br /&gt;
   cuantificadores. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly2a : forall (n m : nat),&lt;br /&gt;
    (n,n) = (m,m)  -&amp;gt;&lt;br /&gt;
    (forall (q r : nat), (q,q) = (r,r) -&amp;gt; [q] = [r]) -&amp;gt;&lt;br /&gt;
    [n] = [m].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m eq1 eq2.&lt;br /&gt;
  (* [n] = [m] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
  (* (n, n) = (m, m) *)&lt;br /&gt;
  apply eq1.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Demostrar, sin usar simpl, que&lt;br /&gt;
      (forall n, evenb n = true -&amp;gt; oddb (S n) = true) -&amp;gt;&lt;br /&gt;
      evenb 3 = true -&amp;gt;&lt;br /&gt;
      oddb 4 = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem silly_ex :&lt;br /&gt;
  (forall n, evenb n = true -&amp;gt; oddb (S n) = true) -&amp;gt;&lt;br /&gt;
  evenb 3 = true -&amp;gt;&lt;br /&gt;
  oddb 4 = true.&lt;br /&gt;
Proof.&lt;br /&gt;
   intros h1 h2.&lt;br /&gt;
  apply h1.&lt;br /&gt;
  apply h2.&lt;br /&gt;
Qed.&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo e necesidad de usar symmetry antes de apply.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly3_firsttry : forall (n : nat),&lt;br /&gt;
    true = beq_nat n 5  -&amp;gt;&lt;br /&gt;
    beq_nat (S (S n)) 7 = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n H.&lt;br /&gt;
  (* beq_nat (S (S n)) 7 = true *)&lt;br /&gt;
  symmetry.&lt;br /&gt;
  (* true = beq_nat (S (S n)) 7 *)&lt;br /&gt;
  simpl.&lt;br /&gt;
  (* true = beq_nat n 5 *)&lt;br /&gt;
  apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Demostrar&lt;br /&gt;
      forall (l l&amp;#039; : list nat), l = rev l&amp;#039; -&amp;gt; l&amp;#039; = rev l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5*)&lt;br /&gt;
Theorem rev_exercise1:&lt;br /&gt;
  forall (l l&amp;#039; : list nat), l = rev l&amp;#039; -&amp;gt; l&amp;#039; = rev l.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros l l&amp;#039;.&lt;br /&gt;
  pattern l.&lt;br /&gt;
  rewrite &amp;lt;- rev_involutive.&lt;br /&gt;
  intros h1.&lt;br /&gt;
  rewrite h1.&lt;br /&gt;
  rewrite rev_involutive.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § La táctica apply ... with ...&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Con dos reescrituras.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_example : forall (a b c d e f : nat),&lt;br /&gt;
    [a;b] = [c;d] -&amp;gt;&lt;br /&gt;
    [c;d] = [e;f] -&amp;gt;&lt;br /&gt;
    [a;b] = [e;f].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros a b c d e f eq1 eq2.&lt;br /&gt;
  (* [a; b] = [e; f] *)&lt;br /&gt;
  rewrite -&amp;gt; eq1.&lt;br /&gt;
  (* [c; d] = [e; f] *)&lt;br /&gt;
  rewrite -&amp;gt; eq2.&lt;br /&gt;
  (* [e; f] = [e; f] *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de lema para simplificar la demostración anterior.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem trans_eq : forall (X:Type) (n m o : X),&lt;br /&gt;
    n = m -&amp;gt; m = o -&amp;gt; n = o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X n m o eq1 eq2.&lt;br /&gt;
  (* n = o *)&lt;br /&gt;
  rewrite -&amp;gt; eq1.&lt;br /&gt;
  (* m = o *)&lt;br /&gt;
  rewrite -&amp;gt; eq2.&lt;br /&gt;
  (* o = o *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. De simplificación de la prueba usando el lema.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_example&amp;#039; : forall (a b c d e f : nat),&lt;br /&gt;
    [a;b] = [c;d] -&amp;gt;&lt;br /&gt;
    [c;d] = [e;f] -&amp;gt;&lt;br /&gt;
    [a;b] = [e;f].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros a b c d e f eq1 eq2.&lt;br /&gt;
  (* [a; b] = [e; f] *)&lt;br /&gt;
  apply trans_eq with (m:=[c;d]).&lt;br /&gt;
  (* [a; b] = [c; d]&lt;br /&gt;
     [c; d] = [e; f] *) &lt;br /&gt;
  apply eq1.&lt;br /&gt;
  (* [c; d] = [e; f] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Simplificación de la prueba anterior.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_example&amp;#039;&amp;#039; : forall (a b c d e f : nat),&lt;br /&gt;
    [a;b] = [c;d] -&amp;gt;&lt;br /&gt;
    [c;d] = [e;f] -&amp;gt;&lt;br /&gt;
    [a;b] = [e;f].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros a b c d e f eq1 eq2.&lt;br /&gt;
  (* [a; b] = [e; f] *)&lt;br /&gt;
  apply trans_eq with [c;d].&lt;br /&gt;
  (* [a; b] = [c; d]&lt;br /&gt;
     [c; d] = [e; f] *) &lt;br /&gt;
  apply eq1.&lt;br /&gt;
  (* [c; d] = [e; f] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Demostrar que&lt;br /&gt;
      forall (n m o p : nat),&lt;br /&gt;
        m = (minustwo o) -&amp;gt;&lt;br /&gt;
        (n + p) = m -&amp;gt;&lt;br /&gt;
        (n + p) = (minustwo o).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
(* alerodrod5*)&lt;br /&gt;
Example trans_eq_exercise : forall (n m o p : nat),&lt;br /&gt;
     m = (minustwo o) -&amp;gt;&lt;br /&gt;
     (n + p) = m -&amp;gt;&lt;br /&gt;
     (n + p) = (minustwo o).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p h1 h2.&lt;br /&gt;
  rewrite h2.&lt;br /&gt;
  rewrite h1.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § La táctica inversión&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración con inversión sobre los naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem S_injective : forall (n m : nat),&lt;br /&gt;
  S n = S m -&amp;gt;&lt;br /&gt;
  n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  (* n : nat&lt;br /&gt;
     m : nat&lt;br /&gt;
     H : S n = S m *) &lt;br /&gt;
  inversion H.&lt;br /&gt;
  (* H1 : n = m *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de inversión generando varias hipótesis.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex1 : forall (n m o : nat),&lt;br /&gt;
    [n; m] = [o; o] -&amp;gt;&lt;br /&gt;
    [n] = [m].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o H.&lt;br /&gt;
  (* n : nat&lt;br /&gt;
     m : nat&lt;br /&gt;
     o : nat&lt;br /&gt;
     H : [n; m] = [o; o] *)&lt;br /&gt;
  inversion H.&lt;br /&gt;
  (* H1 : n = o&lt;br /&gt;
     H2 : m = o *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de nombramiento de las hipótesis generadas por inversión.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex2 : forall (n m : nat),&lt;br /&gt;
    [n] = [m] -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  (* n : nat&lt;br /&gt;
     m : nat&lt;br /&gt;
     H : [n] = [m] *)&lt;br /&gt;
  inversion H as [Hnm].&lt;br /&gt;
  (* Hnm : n = m *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Demostrar que&lt;br /&gt;
      forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
        x :: y :: l = z :: j -&amp;gt;&lt;br /&gt;
        y :: l = x :: j -&amp;gt;&lt;br /&gt;
        x = y.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Example inversion_ex3 : forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
  x :: y :: l = z :: j -&amp;gt;&lt;br /&gt;
  y :: l = x :: j -&amp;gt;&lt;br /&gt;
  x = y.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X x y z l j.&lt;br /&gt;
  inversion 1.&lt;br /&gt;
  inversion 1.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración por inversión basada en que los constructores&lt;br /&gt;
   son disjuntos.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_nat_0_l : forall n,&lt;br /&gt;
    beq_nat 0 n = true -&amp;gt; n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  (* beq_nat 0 n = true -&amp;gt; n = 0 *)&lt;br /&gt;
  destruct n as [| n&amp;#039;].&lt;br /&gt;
  - (* beq_nat 0 0 = true -&amp;gt; 0 = 0 *)&lt;br /&gt;
    intros H.&lt;br /&gt;
    (* 0 = 0 *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* beq_nat 0 (S n&amp;#039;) = true -&amp;gt; S n&amp;#039; = 0 *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* false = true -&amp;gt; S n&amp;#039; = 0 *)&lt;br /&gt;
    intros H.&lt;br /&gt;
    (* S n&amp;#039; = 0 *)&lt;br /&gt;
    inversion H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplos de demostración por inversión sobre los booleanos.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex4 : forall (n : nat),&lt;br /&gt;
    S n = O -&amp;gt;&lt;br /&gt;
    2 + 2 = 5.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n contra.&lt;br /&gt;
  inversion contra.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex5 : forall (n m : nat),&lt;br /&gt;
    false = true -&amp;gt;&lt;br /&gt;
    [n] = [m].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m contra.&lt;br /&gt;
  inversion contra.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Demostrar que&lt;br /&gt;
      forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
        x :: y :: l = [] -&amp;gt;&lt;br /&gt;
        y :: l = z :: j -&amp;gt;&lt;br /&gt;
        x = z.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(*alerodrod5*)&lt;br /&gt;
Example inversion_ex6 :&lt;br /&gt;
  forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
    x :: y :: l = [] -&amp;gt;&lt;br /&gt;
    y :: l = z :: j -&amp;gt;&lt;br /&gt;
    x = z.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X x y z l j.&lt;br /&gt;
  inversion 1.&lt;br /&gt;
Qed.&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de lema que usaremos más tarde.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem f_equal : forall (A B : Type) (f: A -&amp;gt; B) (x y: A),&lt;br /&gt;
    x = y -&amp;gt; f x = f y.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros A B f x y eq.&lt;br /&gt;
  rewrite eq.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Uso de tácticas sobre las hipótesis&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración con &amp;quot;simpl in ...&amp;quot;&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem S_inj : forall (n m : nat) (b : bool),&lt;br /&gt;
    beq_nat (S n) (S m) = b  -&amp;gt;&lt;br /&gt;
    beq_nat n m = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m b H.&lt;br /&gt;
  (* H : beq_nat (S n) (S m) = b *)&lt;br /&gt;
  simpl in H.&lt;br /&gt;
  (* H : beq_nat n m = b *)&lt;br /&gt;
  apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de &amp;quot;razonamiento hacia adelante&amp;quot; con &amp;quot;apply L in H&amp;quot;.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly3&amp;#039; : forall (n : nat),&lt;br /&gt;
  (beq_nat n 5 = true -&amp;gt; beq_nat (S (S n)) 7 = true) -&amp;gt;&lt;br /&gt;
  true = beq_nat n 5  -&amp;gt;&lt;br /&gt;
  true = beq_nat (S (S n)) 7.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n eq H.&lt;br /&gt;
  (* eq : beq_nat n 5 = true -&amp;gt; beq_nat (S (S n)) 7 = true&lt;br /&gt;
     H : true = beq_nat n 5 *)&lt;br /&gt;
  symmetry in H.&lt;br /&gt;
  (* H : beq_nat n 5 = true *)&lt;br /&gt;
  apply eq in H.&lt;br /&gt;
  (* H : beq_nat (S (S n)) 7 = true *)&lt;br /&gt;
  symmetry in H.&lt;br /&gt;
  (* H : true = beq_nat (S (S n)) 7 *)&lt;br /&gt;
  apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar&lt;br /&gt;
      forall n m,&lt;br /&gt;
        n + n = m + m -&amp;gt;&lt;br /&gt;
        n = m.&lt;br /&gt;
&lt;br /&gt;
   Nota: Usar plus_n_Sm&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_n_n_injective :&lt;br /&gt;
  forall n m,&lt;br /&gt;
    n + n = m + m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  induction n as [| n&amp;#039;].&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Control de la hipótesis de inducción  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de necesidad de controlar la hipótesis de inducción.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem double_injective_FAILED : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  induction n as [| n&amp;#039;].&lt;br /&gt;
  - (* double 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    intros eq.&lt;br /&gt;
    (* 0 = m *)&lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* 0 = O *)&lt;br /&gt;
      reflexivity.&lt;br /&gt;
    + (* 0 = S m&amp;#039; *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
  - (* double (S n&amp;#039;) = double m -&amp;gt; S n&amp;#039; = m *)&lt;br /&gt;
    intros eq.&lt;br /&gt;
    (* S n&amp;#039; = m *) &lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* S n&amp;#039; = 0 *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
    + (* S n&amp;#039; = S m&amp;#039; *)&lt;br /&gt;
      apply f_equal.&lt;br /&gt;
      (* n&amp;#039; = m&amp;#039; *)&lt;br /&gt;
      Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem double_injective : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  induction n as [| n&amp;#039;].&lt;br /&gt;
  - (* forall m : nat, double 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* forall m : nat, 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    intros m eq.&lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* 0 = O *)&lt;br /&gt;
      reflexivity.&lt;br /&gt;
    + (* 0 = S m&amp;#039; *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
  - (* IHn&amp;#039; : forall m : nat, double n&amp;#039; = double m -&amp;gt; n&amp;#039; = m&lt;br /&gt;
       forall m : nat, double (S n&amp;#039;) = double m -&amp;gt; S n&amp;#039; = m *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* forall m : nat, S (S (double n&amp;#039;)) = double m -&amp;gt; S n&amp;#039; = m *)&lt;br /&gt;
    intros m eq.&lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* S n&amp;#039; = O *)&lt;br /&gt;
      simpl.&lt;br /&gt;
      inversion eq.&lt;br /&gt;
    + (* S n&amp;#039; = S m&amp;#039; *)&lt;br /&gt;
      apply f_equal.&lt;br /&gt;
      (* n&amp;#039; = m&amp;#039; *)&lt;br /&gt;
      apply IHn&amp;#039;.&lt;br /&gt;
      (* double n&amp;#039; = double m&amp;#039; *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
      (* double n&amp;#039; = double n&amp;#039; *)&lt;br /&gt;
      reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Comentario sobre la estrategia de generalización.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que&lt;br /&gt;
      forall n m,&lt;br /&gt;
        beq_nat n m = true -&amp;gt; n = m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem beq_nat_true : forall n m,&lt;br /&gt;
    beq_nat n m = true -&amp;gt; n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
 induction n.&lt;br /&gt;
  + induction m.&lt;br /&gt;
    - simpl; reflexivity.&lt;br /&gt;
    - simpl; inversion 1.&lt;br /&gt;
  + induction m.&lt;br /&gt;
    - simpl; inversion 1.&lt;br /&gt;
    - intros h1.&lt;br /&gt;
      simpl in h1.&lt;br /&gt;
      apply IHn in h1.&lt;br /&gt;
      rewrite h1; reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de problema por usar intros antes que induction.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Theorem double_injective_take2_FAILED : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  induction m as [| m&amp;#039;].&lt;br /&gt;
  - (* m = O *) simpl. intros eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) reflexivity.&lt;br /&gt;
    + (* n = S n&amp;#039; *) inversion eq.&lt;br /&gt;
  - (* m = S m&amp;#039; *) intros eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) inversion eq.&lt;br /&gt;
    + (* n = S n&amp;#039; *) apply f_equal.&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo con la táctica &amp;quot;generalize dependent&amp;quot;&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem double_injective_take2 : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  generalize dependent n.&lt;br /&gt;
  induction m as [| m&amp;#039;].&lt;br /&gt;
  - (* m = O *) simpl. intros n eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) reflexivity.&lt;br /&gt;
    + (* n = S n&amp;#039; *) inversion eq.&lt;br /&gt;
  - (* m = S m&amp;#039; *) intros n eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) inversion eq.&lt;br /&gt;
    + (* n = S n&amp;#039; *) apply f_equal. apply IHm&amp;#039;. inversion eq. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Lema para iso posterior.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_id_true : forall x y,&lt;br /&gt;
  beq_id x y = true -&amp;gt; x = y.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [m] [n]. simpl. intros H.&lt;br /&gt;
  assert (H&amp;#039; : m = n). { apply beq_nat_true. apply H. }&lt;br /&gt;
  rewrite H&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Demostra, por inducción sobre l,&lt;br /&gt;
      forall (n : nat) (X : Type) (l : list X),&lt;br /&gt;
        length l = n -&amp;gt;&lt;br /&gt;
        nth_error l n = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem nth_error_after_last:&lt;br /&gt;
  forall (n : nat) (X : Type) (l : list X),&lt;br /&gt;
    length l = n -&amp;gt;&lt;br /&gt;
    nth_error l n = None.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Expnasión de definiciones &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de expansión de una definición con unfold.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition square n := n * n.&lt;br /&gt;
&lt;br /&gt;
Lemma square_mult : forall n m, square (n * m) = square n * square m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  simpl. (* no hace nada *)&lt;br /&gt;
  unfold square.&lt;br /&gt;
  rewrite mult_assoc.&lt;br /&gt;
  assert (H : n * m * n = n * n * m).&lt;br /&gt;
  { rewrite mult_comm.&lt;br /&gt;
    apply mult_assoc. }&lt;br /&gt;
  rewrite H. rewrite mult_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de expansión automática de definiciones.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition foo (x: nat) := 5.&lt;br /&gt;
&lt;br /&gt;
Fact silly_fact_1 : forall m, foo m + 1 = foo (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  simpl.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de no expansión automática de definiciones.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition bar x :=&lt;br /&gt;
  match x with&lt;br /&gt;
  | O   =&amp;gt; 5&lt;br /&gt;
  | S _ =&amp;gt; 5&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Fact silly_fact_2_FAILED : forall m, bar m + 1 = bar (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  simpl. (* No hace nada *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Demostración con destruct *)&lt;br /&gt;
Fact silly_fact_2 : forall m, bar m + 1 = bar (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  destruct m.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Demostración con unfold *)&lt;br /&gt;
Fact silly_fact_2&amp;#039; : forall m, bar m + 1 = bar (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  unfold bar.&lt;br /&gt;
  destruct m.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Uso de destruct sobre expresiones compuestas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplos de uso de destruct sobre expresiones compuestas.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sillyfun (n : nat) : bool :=&lt;br /&gt;
  if      beq_nat n 3 then false&lt;br /&gt;
  else if beq_nat n 5 then false&lt;br /&gt;
  else                     false.&lt;br /&gt;
&lt;br /&gt;
Theorem sillyfun_false : forall (n : nat),&lt;br /&gt;
    sillyfun n = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. unfold sillyfun.&lt;br /&gt;
  destruct (beq_nat n 3).&lt;br /&gt;
    - (* beq_nat n 3 = true *) reflexivity.&lt;br /&gt;
    - (* beq_nat n 3 = false *) destruct (beq_nat n 5).&lt;br /&gt;
      + (* beq_nat n 5 = true *) reflexivity.&lt;br /&gt;
      + (* beq_nat n 5 = false *) reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Se define la función split por&lt;br /&gt;
      Fixpoint split {X Y : Type} (l : list (X*Y))&lt;br /&gt;
                     : (list X) * (list Y) :=&lt;br /&gt;
        match l with&lt;br /&gt;
        | [] =&amp;gt; ([], [])&lt;br /&gt;
        | (x, y) :: t =&amp;gt;&lt;br /&gt;
            match split t with&lt;br /&gt;
            | (lx, ly) =&amp;gt; (x :: lx, y :: ly)&lt;br /&gt;
            end&lt;br /&gt;
        end.&lt;br /&gt;
&lt;br /&gt;
   Demostrar que split y combine son inversas; es decir,&lt;br /&gt;
        forall X Y (l : list (X * Y)) l1 l2,&lt;br /&gt;
          split l = (l1, l2) -&amp;gt;&lt;br /&gt;
          combine l1 l2 = l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint split {X Y : Type} (l : list (X*Y))&lt;br /&gt;
               : (list X) * (list Y) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | [] =&amp;gt; ([], [])&lt;br /&gt;
  | (x, y) :: t =&amp;gt;&lt;br /&gt;
      match split t with&lt;br /&gt;
      | (lx, ly) =&amp;gt; (x :: lx, y :: ly)&lt;br /&gt;
      end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(*alerodrod5*)&lt;br /&gt;
Theorem combine_split :&lt;br /&gt;
  forall X Y (l : list (X * Y)) l1 l2,&lt;br /&gt;
    split l = (l1, l2) -&amp;gt;&lt;br /&gt;
    combine l1 l2 = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|(x, y) l&amp;#039;].&lt;br /&gt;
  + intros l1 l2 h1.&lt;br /&gt;
    simpl in h1.&lt;br /&gt;
    inversion h1.&lt;br /&gt;
    simpl; reflexivity.&lt;br /&gt;
  + simpl.&lt;br /&gt;
    destruct (split l&amp;#039;) as [xs ys]. (* The KEY step! *)&lt;br /&gt;
    intros l1 l2 h1.&lt;br /&gt;
    inversion h1.&lt;br /&gt;
    simpl.&lt;br /&gt;
    rewrite IHl&amp;#039;; reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de precauciones al usar destruct para no perder información.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sillyfun1 (n : nat) : bool :=&lt;br /&gt;
  if      beq_nat n 3 then true&lt;br /&gt;
  else if beq_nat n 5 then true&lt;br /&gt;
  else                     false.&lt;br /&gt;
&lt;br /&gt;
Theorem sillyfun1_odd_FAILED : forall (n : nat),&lt;br /&gt;
    sillyfun1 n = true -&amp;gt;&lt;br /&gt;
    oddb n = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n eq. unfold sillyfun1 in eq.&lt;br /&gt;
  destruct (beq_nat n 3).&lt;br /&gt;
  (* Falso por falta de información *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Solución usando destruct con eqn *)&lt;br /&gt;
Theorem sillyfun1_odd : forall (n : nat),&lt;br /&gt;
    sillyfun1 n = true -&amp;gt;&lt;br /&gt;
    oddb n = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n eq. unfold sillyfun1 in eq.&lt;br /&gt;
  destruct (beq_nat n 3) eqn:Heqe3.&lt;br /&gt;
    - (* e3 = true *) apply beq_nat_true in Heqe3.&lt;br /&gt;
      rewrite -&amp;gt; Heqe3. reflexivity.&lt;br /&gt;
    - (* e3 = false *)&lt;br /&gt;
      destruct (beq_nat n 5) eqn:Heqe5.&lt;br /&gt;
        + (* e5 = true *)&lt;br /&gt;
          apply beq_nat_true in Heqe5.&lt;br /&gt;
          rewrite -&amp;gt; Heqe5. reflexivity.&lt;br /&gt;
        + (* e5 = false *) inversion eq.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
      forall (f : bool -&amp;gt; bool) (b : bool),&lt;br /&gt;
        f (f (f b)) = f b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bool_fn_applied_thrice :&lt;br /&gt;
  forall (f : bool -&amp;gt; bool) (b : bool),&lt;br /&gt;
    f (f (f b)) = f b.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Resumen de tácticas básicas &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Tácticas básicas:&lt;br /&gt;
   - [intros]: move hypotheses/variables from goal to context&lt;br /&gt;
&lt;br /&gt;
   - [reflexivity]: finish the proof (when the goal looks like [e = e])&lt;br /&gt;
&lt;br /&gt;
   - [apply]: prove goal using a hypothesis, lemma, or constructor&lt;br /&gt;
&lt;br /&gt;
   - [apply... in H]: apply a hypothesis, lemma, or constructor to&lt;br /&gt;
     a hypothesis in the context (forward reasoning)&lt;br /&gt;
&lt;br /&gt;
   - [apply... with...]: explicitly specify values for variables&lt;br /&gt;
     that cannot be determined by pattern matching&lt;br /&gt;
&lt;br /&gt;
   - [simpl]: simplify computations in the goal&lt;br /&gt;
&lt;br /&gt;
   - [simpl in H]: ... or a hypothesis&lt;br /&gt;
&lt;br /&gt;
   - [rewrite]: use an equality hypothesis (or lemma) to rewrite&lt;br /&gt;
     the goal&lt;br /&gt;
&lt;br /&gt;
   - [rewrite ... in H]: ... or a hypothesis&lt;br /&gt;
&lt;br /&gt;
   - [symmetry]: changes a goal of the form [t=u] into [u=t]&lt;br /&gt;
&lt;br /&gt;
   - [symmetry in H]: changes a hypothesis of the form [t=u] into [u=t]&lt;br /&gt;
&lt;br /&gt;
   - [unfold]: replace a defined constant by its right-hand side in&lt;br /&gt;
     the goal&lt;br /&gt;
&lt;br /&gt;
   - [unfold... in H]: ... or a hypothesis&lt;br /&gt;
&lt;br /&gt;
   - [destruct... as...]: case analysis on values of inductively&lt;br /&gt;
     defined types&lt;br /&gt;
&lt;br /&gt;
   - [destruct... eqn:...]: specify the name of an equation to be&lt;br /&gt;
     added to the context, recording the result of the case analysis&lt;br /&gt;
&lt;br /&gt;
   - [induction... as...]: induction on values of inductively&lt;br /&gt;
     defined types&lt;br /&gt;
&lt;br /&gt;
   - [inversion]: reason by injectivity and distinctness of constructors&lt;br /&gt;
&lt;br /&gt;
   - [assert (H: e)] (or [assert (e) as H]): introduce a &amp;quot;local&lt;br /&gt;
     lemma&amp;quot; [e] and call it [H]&lt;br /&gt;
&lt;br /&gt;
   - [generalize dependent x]: move the variable [x] (and anything&lt;br /&gt;
     else that depends on it) from the context back to an explicit&lt;br /&gt;
     hypothesis in the goal formula *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. Demostrar que&lt;br /&gt;
      forall (n m : nat),&lt;br /&gt;
        beq_nat n m = beq_nat m n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem beq_nat_sym :&lt;br /&gt;
  forall (n m : nat),&lt;br /&gt;
    beq_nat n m = beq_nat m n.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction n, m.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl; apply IHn.&lt;br /&gt;
Qed.&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 12. Demostrar que&lt;br /&gt;
        forall n m p,&lt;br /&gt;
          beq_nat n m = true -&amp;gt;&lt;br /&gt;
          beq_nat m p = true -&amp;gt;&lt;br /&gt;
          beq_nat n p = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_nat_trans :&lt;br /&gt;
  forall n m p,&lt;br /&gt;
    beq_nat n m = true -&amp;gt;&lt;br /&gt;
    beq_nat m p = true -&amp;gt;&lt;br /&gt;
    beq_nat n p = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 13. We proved, in an exercise above, that for all lists of&lt;br /&gt;
   pairs, [combine] is the inverse of [split].  How would you formalize&lt;br /&gt;
   the statement that [split] is the inverse of [combine]?  When is this &lt;br /&gt;
   property true?&lt;br /&gt;
&lt;br /&gt;
   Complete the definition of [split_combine_statement] below with a&lt;br /&gt;
   property that states that [split] is the inverse of&lt;br /&gt;
   [combine]. Then, prove that the property holds. (Be sure to leave&lt;br /&gt;
   your induction hypothesis general by not doing [intros] on more&lt;br /&gt;
   things than necessary.  Hint: what property do you need of [l1]&lt;br /&gt;
   and [l2] for [split] [combine l1 l2 = (l1,l2)] to be true?) &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition split_combine_statement : Prop&lt;br /&gt;
  (* (&amp;quot;[: Prop]&amp;quot; means that we are giving a name to a&lt;br /&gt;
     logical proposition here.) *)&lt;br /&gt;
  := forall (X : Type) (l1 l2 : list X),&lt;br /&gt;
    length l1 = length l2 -&amp;gt; split (combine l1 l2) = (l1,l2).&lt;br /&gt;
&lt;br /&gt;
Theorem length_nil : forall (X : Type) (l : list X),&lt;br /&gt;
    length l = 0 -&amp;gt; l = [].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - inversion H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem split_combine : split_combine_statement.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro. induction l1 as [| h1 l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - simpl. intros. symmetry in H. apply length_nil in H.&lt;br /&gt;
    rewrite H. reflexivity.&lt;br /&gt;
  - induction l2 as [| h2 l2&amp;#039; IHl2&amp;#039;].&lt;br /&gt;
    + simpl. intro. inversion H.&lt;br /&gt;
    + intro. destruct (split (combine l1&amp;#039; l2&amp;#039;)) as [s s&amp;#039;].&lt;br /&gt;
      inversion H. apply IHl1&amp;#039; in H1. simpl.&lt;br /&gt;
      destruct (split (combine l1&amp;#039; l2&amp;#039;)) as [l1&amp;#039;&amp;#039; l2&amp;#039;&amp;#039;].&lt;br /&gt;
      inversion H1. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
(** **** Exercise: 3 stars, advanced (filter_exercise)  *)&lt;br /&gt;
(** This one is a bit challenging.  Pay attention to the form of your&lt;br /&gt;
    induction hypothesis. *)&lt;br /&gt;
&lt;br /&gt;
Theorem filter_exercise : forall (X : Type) (test : X -&amp;gt; bool)&lt;br /&gt;
                             (x : X) (l lf : list X),&lt;br /&gt;
     filter test l = x :: lf -&amp;gt;&lt;br /&gt;
     test x = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros. generalize dependent lf. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - intros. inversion H.&lt;br /&gt;
  - intros. simpl in H. destruct (test n) eqn:IH.&lt;br /&gt;
    + induction lf as [| m lf&amp;#039; IHlf&amp;#039;].&lt;br /&gt;
      * inversion H. rewrite &amp;lt;- H1. apply IH.&lt;br /&gt;
      * inversion H. rewrite &amp;lt;- H1. apply IH.&lt;br /&gt;
    + apply IHl&amp;#039; in H. apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
(** **** Exercise: 4 stars, advanced, recommended (forall_exists_challenge)  *) &lt;br /&gt;
(** Define two recursive [Fixpoints], [forallb] and [existsb].  The&lt;br /&gt;
    first checks whether every element in a list satisfies a given&lt;br /&gt;
    predicate:&lt;br /&gt;
&lt;br /&gt;
      forallb oddb [1;3;5;7;9] = true&lt;br /&gt;
&lt;br /&gt;
      forallb negb [false;false] = true&lt;br /&gt;
&lt;br /&gt;
      forallb evenb [0;2;4;5] = false&lt;br /&gt;
&lt;br /&gt;
      forallb (beq_nat 5) [] = true&lt;br /&gt;
&lt;br /&gt;
    The second checks whether there exists an element in the list that&lt;br /&gt;
    satisfies a given predicate:&lt;br /&gt;
&lt;br /&gt;
      existsb (beq_nat 5) [0;2;3;6] = false&lt;br /&gt;
&lt;br /&gt;
      existsb (andb true) [true;true;false] = true&lt;br /&gt;
&lt;br /&gt;
      existsb oddb [1;0;0;0;0;3] = true&lt;br /&gt;
&lt;br /&gt;
      existsb evenb [] = false&lt;br /&gt;
&lt;br /&gt;
    Next, define a _nonrecursive_ version of [existsb] -- call it&lt;br /&gt;
    [existsb&amp;#039;] -- using [forallb] and [negb].&lt;br /&gt;
&lt;br /&gt;
    Finally, prove a theorem [existsb_existsb&amp;#039;] stating that&lt;br /&gt;
    [existsb&amp;#039;] and [existsb] have the same behavior. *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint forallb {X : Type} (test : X -&amp;gt; bool) (l : list X) : bool :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []      =&amp;gt; true&lt;br /&gt;
  | n :: l&amp;#039; =&amp;gt; if test n then forallb test l&amp;#039; else false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example forallb_1 : forallb oddb [1;3;5;7;9] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example forallb_2 : forallb negb [false;false] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example forallb_3 : forallb evenb [0;2;4;5] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example forallb_4 : forallb (beq_nat 5) [] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Fixpoint existsb {X : Type} (test : X -&amp;gt; bool) (l : list X) : bool :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []      =&amp;gt; false&lt;br /&gt;
  | n :: l&amp;#039; =&amp;gt; if test n then true else existsb test l&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example existsb_1 : existsb (beq_nat 5) [0;2;3;6] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example existsb_2 : existsb (andb true) [true;true;false] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example existsb_3 : existsb oddb [1;0;0;0;0;3] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example existsb_4 : existsb evenb [] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Definition existsb&amp;#039; {X : Type} (test : X -&amp;gt; bool) (l : list X) : bool :=&lt;br /&gt;
  negb (forallb (fun x =&amp;gt; negb (test x)) l).&lt;br /&gt;
&lt;br /&gt;
Theorem existsb_existsb&amp;#039; : forall (X : Type) (test : X -&amp;gt; bool)&lt;br /&gt;
                                  (l : list X),&lt;br /&gt;
    existsb test l = existsb&amp;#039; test l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct (test n) eqn:I.&lt;br /&gt;
    + unfold existsb&amp;#039;. simpl. rewrite I. simpl. reflexivity.&lt;br /&gt;
    + unfold existsb&amp;#039;. rewrite IHl&amp;#039;. simpl. rewrite I. simpl.&lt;br /&gt;
      reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
(** [] *)&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/SLC2018/index.php?title=Tema_4&amp;diff=122</id>
		<title>Tema 4</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_4&amp;diff=122"/>
		<updated>2018-07-15T10:59:45Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;coq&amp;quot;&amp;gt;&lt;br /&gt;
(* T4: Polimorfismo y funciones deo orden superior en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T3_Listas.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Polimorfismo&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Listas polimórficas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo boollist para representar las listas de&lt;br /&gt;
   booleanos con los constructores bool_nil y bool_cons tales que &lt;br /&gt;
   + bool_nil es la lista vacía y&lt;br /&gt;
   + (bool_cons x ys) es la lista obtenida añadiendo el booleano x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive boollist : Type :=&lt;br /&gt;
  | bool_nil : boollist&lt;br /&gt;
  | bool_cons : bool -&amp;gt; boollist -&amp;gt; boollist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (list X) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil es la lista vacía y&lt;br /&gt;
   + (cons x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list (X:Type) : Type :=&lt;br /&gt;
  | nil  : list X&lt;br /&gt;
  | cons : X -&amp;gt; list X -&amp;gt; list X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de list.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check list.&lt;br /&gt;
(* ===&amp;gt; list : Type -&amp;gt; Type *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (nil nat).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (nil nat).&lt;br /&gt;
(* ===&amp;gt; nil nat : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 3 (nil nat)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 3 (nil nat)).&lt;br /&gt;
(* ===&amp;gt; cons nat 3 (nil nat) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check nil.&lt;br /&gt;
(* ===&amp;gt; nil : forall X : Type, list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de cons.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check cons.&lt;br /&gt;
(* ===&amp;gt; cons : forall X : Type, X -&amp;gt; list X -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
(* ==&amp;gt; cons nat 2 (cons nat 1 (nil nat)) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat (X : Type) (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (X : Type) (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0 =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat1 :&lt;br /&gt;
  repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat2 :&lt;br /&gt;
  repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Se definen los siguientes tipos&lt;br /&gt;
      Inductive mumble : Type :=&lt;br /&gt;
        | a : mumble&lt;br /&gt;
        | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
        | c : mumble.&lt;br /&gt;
      &lt;br /&gt;
      Inductive grumble (X:Type) : Type :=&lt;br /&gt;
        | d : mumble -&amp;gt; grumble X&lt;br /&gt;
        | e : X -&amp;gt; grumble X.&lt;br /&gt;
  &lt;br /&gt;
   Decidir cuáles de los siguientes expresiones son del tipo (grumble X)&lt;br /&gt;
   para algún X:&lt;br /&gt;
      - [d (b a 5)]&lt;br /&gt;
      - [d mumble (b a 5)]&lt;br /&gt;
      - [d bool (b a 5)]&lt;br /&gt;
      - [e bool true]&lt;br /&gt;
      - [e mumble (b c 0)]&lt;br /&gt;
      - [e bool (b c 0)]&lt;br /&gt;
      - [c]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
Inductive mumble : Type :=&lt;br /&gt;
  | a : mumble&lt;br /&gt;
  | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
  | c : mumble.&lt;br /&gt;
&lt;br /&gt;
Inductive grumble (X:Type) : Type :=&lt;br /&gt;
  | d : mumble -&amp;gt; grumble X&lt;br /&gt;
  | e : X -&amp;gt; grumble X.&lt;br /&gt;
&lt;br /&gt;
End MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inferencia de tipos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat&amp;#039; X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular los tipos de repeat&amp;#039; y repeat.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check repeat&amp;#039;.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
Check repeat.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Síntesis de los tipos de los argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil _&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons _ x (repeat&amp;#039;&amp;#039; _ x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123 :=&lt;br /&gt;
  cons nat 1 (cons nat 2 (cons nat 3 (nil nat))).&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039; :=&lt;br /&gt;
  cons _ 1 (cons _ 2 (cons _ 3 (nil _))).&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Argumentos implícitos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Especificar las siguientes funciones y sus argumentos&lt;br /&gt;
   explícitos e implícitos:&lt;br /&gt;
   + nil&lt;br /&gt;
   + constructor&lt;br /&gt;
   + repeat&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Arguments nil {X}.&lt;br /&gt;
Arguments cons {X} _ _.&lt;br /&gt;
Arguments repeat {X} x count.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039; := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons x (repeat&amp;#039;&amp;#039;&amp;#039; x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;1 :&lt;br /&gt;
  repeat&amp;#039;&amp;#039;&amp;#039; 4 2 = cons 4 (cons 4 nil).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;2 :&lt;br /&gt;
  repeat false 1 = cons false nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (list&amp;#039; {X}) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil&amp;#039; es la lista vacía y&lt;br /&gt;
   + (cons&amp;#039; x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list&amp;#039; {X:Type} : Type :=&lt;br /&gt;
  | nil&amp;#039;  : list&amp;#039;&lt;br /&gt;
  | cons&amp;#039; : X -&amp;gt; list&amp;#039; -&amp;gt; list&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      app {X : Type} (l1 l2 : list X) : (list X)&lt;br /&gt;
   tal que (app xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint app {X : Type} (l1 l2 : list X) : (list X) :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil      =&amp;gt; l2&lt;br /&gt;
  | cons h t =&amp;gt; cons h (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev {X:Type} (l:list X) : list X&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
      rev (cons true nil) = cons true nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev {X:Type} (l:list X) : list X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil      =&amp;gt; nil&lt;br /&gt;
  | cons h t =&amp;gt; app (rev t) (cons h nil)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1 :&lt;br /&gt;
  rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_rev2:&lt;br /&gt;
  rev (cons true nil) = cons true nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length {X : Type} (l : list X) : nat &lt;br /&gt;
   tal que (length xs) es el número de elementos de xs. Por ejemplo,&lt;br /&gt;
      length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil       =&amp;gt; 0&lt;br /&gt;
  | cons _ l&amp;#039; =&amp;gt; S (length l&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_length1:&lt;br /&gt;
  length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Explicitación de argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Especificar que la siguiente definición es errónea&lt;br /&gt;
      Fail Definition mynil := nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fail Definition mynil := nil.&lt;br /&gt;
(* ==&amp;gt; Error: Cannot infer the implicit parameter X of nil. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Completar la definición anterior para obtener la lista&lt;br /&gt;
   vacía de números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mynil : list nat := nil.&lt;br /&gt;
&lt;br /&gt;
(* Alternativamente *)&lt;br /&gt;
Definition mynil&amp;#039; := @nil nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir las siguientes abreviaturas&lt;br /&gt;
   + &amp;quot;x :: y&amp;quot;         para (cons x y)&lt;br /&gt;
   + &amp;quot;[ ]&amp;quot;            para nil&lt;br /&gt;
   + &amp;quot;[ x ; .. ; y ]&amp;quot; para (cons x .. (cons y []) ..).&lt;br /&gt;
   + &amp;quot;x ++ y&amp;quot;         para (app x y)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: y&amp;quot; := (cons x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y []) ..).&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039;&amp;#039; := [1; 2; 3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Ejercicios  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall (X:Type), forall l:list X,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que la concatenación es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall A (l m n:list A),&lt;br /&gt;
  l ++ m ++ n = (l ++ m) ++ n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros A l m n.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que la longitud de una concatenación es la suma de&lt;br /&gt;
   las longitudes de las listas (es decir, es un homomorfismo).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma app_length : forall (X:Type) (l1 l2 : list X),&lt;br /&gt;
  length (l1 ++ l2) = length l1 + length l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X l1 l2.&lt;br /&gt;
  induction l1.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl1. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_app_distr: forall X (l1 l2 : list X),&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X l1 l2.&lt;br /&gt;
  induction l1.&lt;br /&gt;
  + simpl. rewrite app_nil_r. reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl1, app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      rev (rev l) = l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall X : Type, forall l : list X,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite rev_app_distr, IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Polimorfismo de pares  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo prod (X Y) con el constructor pair tal que &lt;br /&gt;
   (pair x y) es el par cuyas componentes son x e y.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive prod (X Y : Type) : Type :=&lt;br /&gt;
| pair : X -&amp;gt; Y -&amp;gt; prod X Y.&lt;br /&gt;
&lt;br /&gt;
Arguments pair {X} {Y} _ _.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;( x , y )&amp;quot; para (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;X * Y&amp;quot; para (prod X Y) &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;X * Y&amp;quot; := (prod X Y) : type_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst {X Y : Type} (p : X * Y) : X&lt;br /&gt;
   tal que (fst p) es la primera componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst {X Y : Type} (p : X * Y) : X :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd {X Y : Type} (p : X * Y) &lt;br /&gt;
   tal que (snd p) es la segunda componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd {X Y : Type} (p : X * Y) : Y :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) &lt;br /&gt;
   tal que (combine lx ly) es la lista obtenida emparejando los&lt;br /&gt;
   elementos de lx y ly (como zip de Haskell).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) :=&lt;br /&gt;
  match lx, ly with&lt;br /&gt;
  | []     , _       =&amp;gt; []&lt;br /&gt;
  | _      , []      =&amp;gt; []&lt;br /&gt;
  | x :: tx, y :: ty =&amp;gt; (x, y) :: (combine tx ty)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Check combine&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check @combine.&lt;br /&gt;
(* ==&amp;gt; forall X Y : Type, list X -&amp;gt; list Y -&amp;gt; list (X * Y)*)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
(* ==&amp;gt; [(1, false); (2, false)] : list (nat * bool) *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y)&lt;br /&gt;
   tal que (split l) es el par de lista (lx,ly) cuyo emparejamiento es&lt;br /&gt;
   l. (La función split es como unzip de Haskell). Por ejemplo,&lt;br /&gt;
      split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y) :=&lt;br /&gt;
 match l with&lt;br /&gt;
 | []          =&amp;gt; ([], [])&lt;br /&gt;
 | (x, y) :: t =&amp;gt; let s := split t in (x :: fst s, y :: snd s)&lt;br /&gt;
end.&lt;br /&gt;
&lt;br /&gt;
Example test_split:&lt;br /&gt;
  split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Resultados opcionales polimórficos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (option X) con los constructores Some y None&lt;br /&gt;
   tales que &lt;br /&gt;
   + (Some x) es un valor de tipo X.&lt;br /&gt;
   + None es el valor nulo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive option (X:Type) : Type :=&lt;br /&gt;
  | Some : X -&amp;gt; option X&lt;br /&gt;
  | None : option X.&lt;br /&gt;
&lt;br /&gt;
Arguments Some {X} _.&lt;br /&gt;
Arguments None {X}.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
   tal que (nth_error l n) es el n-ésimo elemento de l. Por ejemplo, &lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
      nth_error [true] 2    = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []      =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O then Some a else nth_error l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [true] 2 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      hd_error {X : Type} (l : list X) : option X&lt;br /&gt;
   tal que (hd_error l) es el primer elemento de l. Por ejemplo,&lt;br /&gt;
      hd_error [1;2]     = Some 1.&lt;br /&gt;
      hd_error [[1];[2]] = Some [1].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error {X : Type} (l : list X) : option X :=&lt;br /&gt;
 match l with &lt;br /&gt;
    | []     =&amp;gt; None&lt;br /&gt;
    | x :: _ =&amp;gt; Some x&lt;br /&gt;
 end.&lt;br /&gt;
&lt;br /&gt;
Check @hd_error.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [1;2] = Some 1.&lt;br /&gt;
 Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error2 : hd_error  [[1];[2]]  = Some [1].&lt;br /&gt;
 Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones como datos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones de orden superior &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X &lt;br /&gt;
   tal que (doit3times f) aplica 3 veces la función f. Por ejemplo,&lt;br /&gt;
      doit3times minustwo 9 = 3.&lt;br /&gt;
      doit3times negb true  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X :=&lt;br /&gt;
  f (f (f n)).&lt;br /&gt;
&lt;br /&gt;
Check @doit3times.&lt;br /&gt;
(* ===&amp;gt; doit3times : forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X *)&lt;br /&gt;
&lt;br /&gt;
Example test_doit3times: doit3times minustwo 9 = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_doit3times&amp;#039;: doit3times negb true = false.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Filtrado  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      filter {X:Type} (test: X-&amp;gt;bool) (l:list X) : (list X)&lt;br /&gt;
   tal que (filter p l) es la lista de los elementos de l que verifican&lt;br /&gt;
   p. Por ejemplo,&lt;br /&gt;
      filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fixpoint filter {X:Type} (test: X-&amp;gt;bool) (l:list X)&lt;br /&gt;
                : (list X) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; if test h then h :: (filter test t)&lt;br /&gt;
                       else       filter test t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_filter1: filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Definition length_is_1 {X : Type} (l : list X) : bool :=&lt;br /&gt;
  beq_nat (length l) 1.&lt;br /&gt;
&lt;br /&gt;
Example test_filter2:&lt;br /&gt;
    filter length_is_1&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      countoddmembers&amp;#039; (l:list nat) : nat &lt;br /&gt;
   tal que countoddmembers&amp;#039; l) es el número de elementos impares de&lt;br /&gt;
   l. Por ejemplo,&lt;br /&gt;
      countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers&amp;#039; [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers&amp;#039; nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers&amp;#039; (l:list nat) : nat :=&lt;br /&gt;
  length (filter oddb l).&lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers&amp;#039;1:   countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;2:   countoddmembers&amp;#039; [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;3:   countoddmembers&amp;#039; nil = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones anónimas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_anon_fun&amp;#039;:&lt;br /&gt;
  doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular&lt;br /&gt;
      filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
             [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_filter2&amp;#039;:&lt;br /&gt;
    filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      filter_even_gt7 (l : list nat) : list nat&lt;br /&gt;
   tal que (filter_even_gt7 l) es la lista de los elemntos de l que son&lt;br /&gt;
   pares y mayores que 7. Por ejemplo,&lt;br /&gt;
      filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
      filter_even_gt7 [5;2;6;19;129]      = [].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition filter_even_gt7 (l : list nat) : list nat :=&lt;br /&gt;
  filter (fun x =&amp;gt; evenb x &amp;amp;&amp;amp; leb 7 x) l.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_1 :&lt;br /&gt;
  filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
 Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_2 :&lt;br /&gt;
  filter_even_gt7 [5;2;6;19;129] = [].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      partition : forall X : Type,&lt;br /&gt;
                  (X -&amp;gt; bool) -&amp;gt; list X -&amp;gt; list X * list X&lt;br /&gt;
   tal que (patition p l) es el par de lista (lx,ly) tal que lx es la&lt;br /&gt;
   lista de los elementos de l que cumplen p y ly la de las que no lo&lt;br /&gt;
   cumplen. Por ejemplo,&lt;br /&gt;
      partition oddb [1;2;3;4;5]         = ([1;3;5], [2;4]).&lt;br /&gt;
      partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition partition {X : Type}&lt;br /&gt;
                     (test : X -&amp;gt; bool)&lt;br /&gt;
                     (l : list X)&lt;br /&gt;
                   : list X * list X :=&lt;br /&gt;
  (filter test l, filter (fun x =&amp;gt; negb (test x)) l).&lt;br /&gt;
&lt;br /&gt;
Example test_partition1: partition oddb [1;2;3;4;5] = ([1;3;5], [2;4]).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_partition2: partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Aplicación a todos los elementos (map)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) &lt;br /&gt;
   tal que (map f l) es la lista obtenida aplicando f a todos los&lt;br /&gt;
   elementos de l. Por ejemplo,&lt;br /&gt;
      map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
      map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
      map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
        = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; (f h) :: (map f t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_map1: map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map2:&lt;br /&gt;
  map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map3:&lt;br /&gt;
    map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
  = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      map f (rev l) = rev (map f l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma map_app_distr : forall (X Y : Type) (f : X -&amp;gt; Y) (l t : list X),&lt;br /&gt;
    map f (l ++ t) = map f l ++ map f t.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X Y f l t.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem map_rev : forall (X Y : Type) (f : X -&amp;gt; Y) (l : list X),&lt;br /&gt;
  map f (rev l) = rev (map f l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X Y f l.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite map_app_distr, IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X) : (list Y)&lt;br /&gt;
   tal que (flat_map f l) es la concatenación de las listas obtenidas&lt;br /&gt;
   aplicando f a l. Por ejemplo,&lt;br /&gt;
      flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4] = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X) &lt;br /&gt;
                   : (list Y) :=&lt;br /&gt;
   match l with&lt;br /&gt;
  | [] =&amp;gt; []&lt;br /&gt;
  | x :: t =&amp;gt; f x ++ flat_map f t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_flat_map1:&lt;br /&gt;
  flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4]&lt;br /&gt;
  = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X) : option Y&lt;br /&gt;
   tal que (option_map f xo) es la aplicación de f a xo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X)&lt;br /&gt;
                      : option Y :=&lt;br /&gt;
  match xo with&lt;br /&gt;
    | None   =&amp;gt; None&lt;br /&gt;
    | Some x =&amp;gt; Some (f x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Plegados (fold)  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y) : Y&lt;br /&gt;
   tal que (fold f l b) es el plegado de l con la operación f a partir&lt;br /&gt;
   del elemento b. Por ejemplo,&lt;br /&gt;
      fold mult [1;2;3;4] 1                 = 24.&lt;br /&gt;
      fold andb [true;true;false;true] true = false.&lt;br /&gt;
      fold app  [[1];[];[2;3];[4]] []       = [1;2;3;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y)&lt;br /&gt;
                         : Y :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; b&lt;br /&gt;
  | h :: t =&amp;gt; f h (fold f t b)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Check (fold andb).&lt;br /&gt;
(* ===&amp;gt; fold andb : list bool -&amp;gt; bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
Example fold_example1 :&lt;br /&gt;
  fold mult [1;2;3;4] 1 = 24.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example2 :&lt;br /&gt;
  fold andb [true;true;false;true] true = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example3 :&lt;br /&gt;
  fold app  [[1];[];[2;3];[4]] [] = [1;2;3;4].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones que construyen funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      constfun {X: Type} (x: X) : nat-&amp;gt;X&lt;br /&gt;
   tal que (constfun x) es la función que a todos los naturales le&lt;br /&gt;
   asigna el x. Por ejemplo, si se define &lt;br /&gt;
      Definition ftrue := constfun true.&lt;br /&gt;
   entonces,&lt;br /&gt;
      ftrue 0         = true.&lt;br /&gt;
      (constfun 5) 99 = 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition constfun {X: Type} (x: X) : nat-&amp;gt;X :=&lt;br /&gt;
  fun (k:nat) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
Definition ftrue := constfun true.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example1 : ftrue 0 = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example2 : (constfun 5) 99 = 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de plus.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check plus.&lt;br /&gt;
(* ==&amp;gt; nat -&amp;gt; nat -&amp;gt; nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus3 : nat -&amp;gt; nat&lt;br /&gt;
   tal que (plus3 x) es tres más x. Por ejemplo,&lt;br /&gt;
      plus3 4               = 7.&lt;br /&gt;
      doit3times plus3 0    = 9.&lt;br /&gt;
      doit3times (plus 3) 0 = 9.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus3 := plus 3.&lt;br /&gt;
&lt;br /&gt;
Example test_plus3 :    plus3 4 = 7.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039; :   doit3times plus3 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039;&amp;#039; :  doit3times (plus 3) 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
Module Exercises.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_length {X : Type} (l : list X) : nat&lt;br /&gt;
   tal que (fold_length l) es la longitud de l. Por ejemplo,&lt;br /&gt;
      fold_length [4;7;0] = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition fold_length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  fold (fun _ n =&amp;gt; S n) l 0.&lt;br /&gt;
&lt;br /&gt;
Example test_fold_length1 : fold_length [4;7;0] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      fold_length l = length l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fold_length_correct : forall X (l : list X),&lt;br /&gt;
  fold_length l = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X l.&lt;br /&gt;
  unfold fold_length.&lt;br /&gt;
  induction l.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y&lt;br /&gt;
   tal que (fold_map f l) es la lista obtenida aplicando f a los&lt;br /&gt;
   elementos de l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y :=&lt;br /&gt;
   fold (fun x t =&amp;gt; (f x) :: t)  l [].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que fold_map es equivalente a map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fold_map_correct : forall (X Y : Type) (f : X -&amp;gt; Y) (l : list X),&lt;br /&gt;
     fold_map f l = map f l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X Y f l.&lt;br /&gt;
  unfold fold_map.&lt;br /&gt;
  induction l.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      prod_curry {X Y Z : Type} (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z&lt;br /&gt;
   tal que (prod_curry f x y) es la versión curryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_curry {X Y Z : Type}&lt;br /&gt;
  (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z := f (x, y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      prod_uncurry {X Y Z : Type} (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z&lt;br /&gt;
   tal que (prod_uncurry f p) es la versión incurryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_uncurry {X Y Z : Type}&lt;br /&gt;
  (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z := f (fst p) (snd p).&lt;br /&gt;
&lt;br /&gt;
Check @prod_curry.&lt;br /&gt;
Check @prod_uncurry.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      prod_curry (prod_uncurry f) x y = f x y&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem uncurry_curry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : X -&amp;gt; Y -&amp;gt; Z)&lt;br /&gt;
                        x y,&lt;br /&gt;
  prod_curry (prod_uncurry f) x y = f x y.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem curry_uncurry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : (X * Y) -&amp;gt; Z) (p : X * Y),&lt;br /&gt;
  prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros.&lt;br /&gt;
  destruct p.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      forall X n l, length l = n -&amp;gt; @nth_error X l n = None&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. En los siguientes ejercicios se trabajará con la&lt;br /&gt;
   definición de Church de los números naturales: el número natural n es&lt;br /&gt;
   la función que toma como argumento una función f y devuelve como&lt;br /&gt;
   valor la aplicación de n veces la función f. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module Church.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo nat para los números naturales de Church. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition nat := forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      one : nat&lt;br /&gt;
   tal que one es el número uno de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition one : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      two : nat&lt;br /&gt;
   tal que two es el número dos de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition two : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f (f x).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      zero : nat&lt;br /&gt;
   tal que zero es el número cero de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition zero : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      three : nat&lt;br /&gt;
   tal que three es el número tres de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition three : nat := @doit3times.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      succ (n : nat) : nat&lt;br /&gt;
   tal que (succ n) es el siguiente del número n de Church. Por ejemplo, &lt;br /&gt;
      succ zero = one.&lt;br /&gt;
      succ one  = two.&lt;br /&gt;
      succ two  = three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition succ (n : nat) : nat :=&lt;br /&gt;
   fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f (n X f x).&lt;br /&gt;
&lt;br /&gt;
Example succ_1 : succ zero = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example succ_2 : succ one = two.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example succ_3 : succ two = three.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      plus (n m : nat) : nat&lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus zero one             = one.&lt;br /&gt;
      plus two three            = plus three two.&lt;br /&gt;
      plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus (n m : nat) : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; m X f (n X f x).&lt;br /&gt;
&lt;br /&gt;
Example plus_1 : plus zero one = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example plus_2 : plus two three = plus three two.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example plus_3 :&lt;br /&gt;
  plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      mult (n m : nat) : nat&lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult one one = one.&lt;br /&gt;
      mult zero (plus three three) = zero.&lt;br /&gt;
      mult two three = plus three three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mult (n m : nat) : nat :=&lt;br /&gt;
   fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; n X (m X f) x.&lt;br /&gt;
&lt;br /&gt;
Example mult_1 : mult one one = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example mult_2 : mult zero (plus three three) = zero.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example mult_3 : mult two three = plus three three.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      exp (n m : nat) : nat&lt;br /&gt;
   tal que (exp n m) es la potencia m-ésima de n. Por ejemplo, &lt;br /&gt;
      exp two two = plus two two.&lt;br /&gt;
      exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
      exp three zero = one.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition exp (n m : nat) : nat :=&lt;br /&gt;
  ( fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; (m (X -&amp;gt; X) (n X) f) x).&lt;br /&gt;
&lt;br /&gt;
Example exp_1 : exp two two = plus two two.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example exp_2 : exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example exp_3 : exp three zero = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
End Church.&lt;br /&gt;
&lt;br /&gt;
End Exercises.&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/SLC2018/index.php?title=Tema_3&amp;diff=121</id>
		<title>Tema 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=121"/>
		<updated>2018-07-15T10:57:33Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;coq&amp;quot;&amp;gt;&lt;br /&gt;
(* T3: Datos estructurados en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T2_Induccion.&lt;br /&gt;
(* La teoría T2_Induccion se encuentra en http://bit.ly/2pDlxlF *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatList. &lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pares de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. El tipo de los números naturales es natprod y su&lt;br /&gt;
   constructor es pair.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natprod : Type :=&lt;br /&gt;
  pair : nat -&amp;gt; nat -&amp;gt; natprod.&lt;br /&gt;
&lt;br /&gt;
Check (pair 3 5).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (fst p) es la primera componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (pair 3 5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (pair 3 5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (snd p) es la segunda componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x,y) como una abreviaura de (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (3,5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (3,5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función fst usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función snd usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      swap_pair : natprod -&amp;gt; natprod&lt;br /&gt;
   tal que (swap_pair p) es el par obtenido intercambiando las&lt;br /&gt;
   componentes de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition swap_pair (p : natprod) : natprod := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; (y,x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todos los naturales&lt;br /&gt;
      (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing&amp;#039; : forall (n m : nat),&lt;br /&gt;
  (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
Proof.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todo par de naturales&lt;br /&gt;
      p = (fst p, snd p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing_stuck : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  simpl. (* No reduce nada. *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros p.  destruct p as [n m].  simpl.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Demostrar que para todo par de naturales p,&lt;br /&gt;
      (snd p, fst p) = swap_pair p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem snd_fst_is_swap : forall (p : natprod),&lt;br /&gt;
  (snd p, fst p) = swap_pair p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Demostrar que para todo par de naturales p,&lt;br /&gt;
      fst (swap_pair p) = snd p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fst_swap_is_snd : forall (p : natprod),&lt;br /&gt;
  fst (swap_pair p) = snd p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Listas de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. natlist es la lista de los números naturales y sus&lt;br /&gt;
   constructores son &lt;br /&gt;
   + nil (la lista vacía) y &lt;br /&gt;
   + cons (tal que (cons x ys) es la lista obtenida añadiéndole x a ys. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natlist : Type :=&lt;br /&gt;
  | nil  : natlist&lt;br /&gt;
  | cons : nat -&amp;gt; natlist -&amp;gt; natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la constante &lt;br /&gt;
      mylist : natlist&lt;br /&gt;
   que es la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x :: ys) como una abreviatura de &lt;br /&gt;
   (cons x ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: l&amp;quot; := (cons x l)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación de las listas finitas escribiendo sus&lt;br /&gt;
   elementos entre corchetes y separados por puntos y comas.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y nil) ..).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Distintas representaciones de mylist.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist1 := 1 :: (2 :: (3 :: nil)).&lt;br /&gt;
Definition mylist2 := 1 :: 2 :: 3 :: nil.&lt;br /&gt;
Definition mylist3 := [1;2;3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Repeat  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat : nat -&amp;gt; nat -&amp;gt; natlist&lt;br /&gt;
   tal que (repeat n k) es la lista formada por k veces el número n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (n count : nat) : natlist :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | O        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; n :: (repeat n count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Length  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (length xs) es el número de elementos de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; O&lt;br /&gt;
  | h :: t =&amp;gt; S (length t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Append  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      append : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (append xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Fixpoint app (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil    =&amp;gt; l2&lt;br /&gt;
  | h :: t =&amp;gt; h :: (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (xs ++ ys) como una abreviaura de &lt;br /&gt;
   (append xs ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (right associativity, at level 60).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
      nil     ++ [4;5] = [4;5].&lt;br /&gt;
      [1;2;3] ++ nil   = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_app1: [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app2: nil ++ [4;5] = [4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app3: [1;2;3] ++ nil = [1;2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Head y tail  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      hd : nat -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (hd d xs) es el primer elemento de xs o d, si xs es la lista&lt;br /&gt;
   vacía. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd (default:nat) (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; default&lt;br /&gt;
  | h :: t =&amp;gt; h&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      tl : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (tl xs) es el resto de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition tl (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
       hd 0 [1;2;3] = 1.&lt;br /&gt;
       hd 0 []      = 0.&lt;br /&gt;
       tl [1;2;3]   = [2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_hd1: hd 0 [1;2;3] = 1.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_hd2: hd 0 [] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_tl: tl [1;2;3] = [2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      nonzeros : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (nonzeros xs) es la lista de los elementos de xs distintos de&lt;br /&gt;
   cero. Por ejemplo,&lt;br /&gt;
      nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | a::bs =&amp;gt; match a with&lt;br /&gt;
            | 0 =&amp;gt; nonzeros bs &lt;br /&gt;
            | _ =&amp;gt;  a:: nonzeros bs end&lt;br /&gt;
 end.&lt;br /&gt;
Example test_nonzeros: nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros2 (l:natlist) : natlist :=&lt;br /&gt;
 match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; if(beq_nat h 0) then nonzeros2 t else h :: nonzeros2 t end.&lt;br /&gt;
&lt;br /&gt;
Example test_nonzeros2: nonzeros2 [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      oddmembers : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (oddmembers xs) es la lista de los elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint oddmembers (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t::xs =&amp;gt; if oddb t then t :: oddmembers xs else oddmembers xs&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example test_oddmembers: oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Definir la función&lt;br /&gt;
      countoddmembers : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (countoddmembers xs) es el número de elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers (l:natlist) : nat :=&lt;br /&gt;
 length (oddmembers l). &lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers1: countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers2: countoddmembers [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers3: countoddmembers nil = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Definir la función&lt;br /&gt;
      alternate : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (alternate xs ys) es la lista obtenida intercalando los&lt;br /&gt;
   elementos de xs e ys. Por ejemplo,&lt;br /&gt;
      alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
      alternate [1] [4;5;6]     = [1;4;5;6].&lt;br /&gt;
      alternate [1;2;3] [4]     = [1;4;2;3].&lt;br /&gt;
      alternate [] [20;30]      = [20;30].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint alternate (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil =&amp;gt; l2&lt;br /&gt;
  | t::xs =&amp;gt; match l2 with&lt;br /&gt;
            | nil =&amp;gt; t::xs&lt;br /&gt;
            | p::ys =&amp;gt; t::p::alternate xs ys end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_alternate1: alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate2: alternate [1] [4;5;6] = [1;4;5;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate3: alternate [1;2;3] [4] = [1;4;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate4: alternate [] [20;30] = [20;30].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Multiconjuntos como listas &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Un multiconjunto es como un conjunto donde los elementos pueden&lt;br /&gt;
   repetirse más de una vez. Podemos implementarlos como listas.  *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo baf de los multiconjuntos de números&lt;br /&gt;
   naturales. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition bag := natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Definir la función&lt;br /&gt;
      count : nat -&amp;gt; bag -&amp;gt; nat &lt;br /&gt;
   tal que (count v s) es el número des veces que aparece el elemento v&lt;br /&gt;
   en el multiconjunto s. Por ejemplo,&lt;br /&gt;
      count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
      count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint count (v:nat) (s:bag) : nat :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil   =&amp;gt; 0&lt;br /&gt;
  | t::xs =&amp;gt; if beq_nat t v&lt;br /&gt;
            then 1 + count v xs&lt;br /&gt;
            else count v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_count1: count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_count2: count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
Proof. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Definir la función&lt;br /&gt;
      sum : bag -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (sum xs ys) es la suma de los multiconjuntos xs e ys. Por&lt;br /&gt;
   ejemplo, &lt;br /&gt;
      count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sum : bag -&amp;gt; bag -&amp;gt; bag := app.&lt;br /&gt;
&lt;br /&gt;
Example test_sum1: count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Definir la función&lt;br /&gt;
      add : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (add x ys) es el multiconjunto obtenido añadiendo el elemento&lt;br /&gt;
   x al multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
      count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition add (v:nat) (s:bag) : bag :=&lt;br /&gt;
  v :: s.&lt;br /&gt;
&lt;br /&gt;
Example test_add1: count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_add2: count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Definir la función&lt;br /&gt;
      member : nat -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (member x ys) se verfica si x pertenece al multiconjunto&lt;br /&gt;
   ys. Por ejemplo,  &lt;br /&gt;
      member 1 [1;4;1] = true.&lt;br /&gt;
      member 2 [1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition member (v:nat) (s:bag) : bool := &lt;br /&gt;
  if beq_nat 0 (count v s)&lt;br /&gt;
  then false&lt;br /&gt;
  else true.&lt;br /&gt;
&lt;br /&gt;
Example test_member1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Definition member2 (v:nat) (s:bag) : bool :=&lt;br /&gt;
  negb (beq_nat O (count v s)).&lt;br /&gt;
&lt;br /&gt;
Example test_member2_1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2_2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. Definir la función&lt;br /&gt;
      remove_one : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_one x ys) es el multiconjunto obtenido eliminando una&lt;br /&gt;
   ocurrencia de x en el multiconjunto ys. Por ejemplo, &lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;1])     = 0.&lt;br /&gt;
      count 4 (remove_one 5 [2;1;4;5;1;4])   = 2.&lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_one (v:nat) (s:bag) : bag :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil     =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then xs&lt;br /&gt;
               else t :: remove_one v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_one1: count 5 (remove_one 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one2: count 5 (remove_one 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one3: count 4 (remove_one 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one4: count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 12. Definir la función&lt;br /&gt;
      remove_all : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_all x ys) es el multiconjunto obtenido eliminando&lt;br /&gt;
   todas las ocurrencias de x en el multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;1])           = 0.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;4;1])             = 0.&lt;br /&gt;
      count 4 (remove_all 5 [2;1;4;5;1;4])         = 2.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_all (v:nat) (s:bag) : bag :=&lt;br /&gt;
   match s with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then remove_all v xs&lt;br /&gt;
               else t :: remove_all v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_all1: count 5 (remove_all 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all2: count 5 (remove_all 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all3: count 4 (remove_all 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all4: count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 13. Definir la función&lt;br /&gt;
      subset : bag -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (subset xs ys) se verifica si xs es un sub,ulticonjunto de&lt;br /&gt;
   ys. Por ejemplo,&lt;br /&gt;
      subset [1;2]   [2;1;4;1] = true.&lt;br /&gt;
      subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint subset (s1:bag) (s2:bag) : bool :=&lt;br /&gt;
  match s1 with&lt;br /&gt;
  | nil   =&amp;gt; true&lt;br /&gt;
  | x::xs =&amp;gt; member x s2 &amp;amp;&amp;amp; subset xs (remove_one x s2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_subset1: subset [1;2] [2;1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_subset2: subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 14. Escribir un teorema sobre multiconjuntos con las funciones&lt;br /&gt;
   count y add y probarlo. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_theorem : forall s1 s2 : bag, forall n : nat,&lt;br /&gt;
  count n s1 + count n s2 = count n (app s1 s2).                 &lt;br /&gt;
Proof.&lt;br /&gt;
  intros s1 s2 n. induction s1 as [|s s&amp;#039;].&lt;br /&gt;
 - simpl. reflexivity.&lt;br /&gt;
 - simpl. destruct (beq_nat s n).&lt;br /&gt;
    + simpl. rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
    + rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Razonamiento sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      [] ++ l = l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem nil_app : forall l:natlist,&lt;br /&gt;
  [] ++ l = l.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      pred (length l) = length (tl l)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem tl_length_pred : forall l:natlist,&lt;br /&gt;
  pred (length l) = length (tl l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. destruct l as [| n l&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons n l&amp;#039; *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Inducción sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la concatenación de listas de naturales es&lt;br /&gt;
   asociativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall l1 l2 l3 : natlist,&lt;br /&gt;
  (l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons n l1&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Comentar los nombres dados en la hipótesis de inducción. *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inversa de una lista  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev [1;2;3] = [3;2;1].&lt;br /&gt;
      rev nil     = nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; rev t ++ [h]&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1: rev [1;2;3] = [3;2;1].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_rev2: rev nil = nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Propiedaes de la función rev  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      length (rev l) = length l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length_firsttry : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = [] *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = n :: l&amp;#039; *)&lt;br /&gt;
    (* Probamos simplificando *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    rewrite &amp;lt;- IHl&amp;#039;.&lt;br /&gt;
    (* Nos encontramos sin más que hacer, así que buscamos un lema que&lt;br /&gt;
       nos ayude. *) &lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem app_length : forall l1 l2 : natlist,&lt;br /&gt;
  length (l1 ++ l2) = (length l1) + (length l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ahora completamos la prueba original. *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; app_length, plus_comm.&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 15. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación de listas. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall l : natlist,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 16. Demostrar que rev es un endomorfismo en (natlist,++)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Theorem rev_app_distr: forall l1 l2 : natlist,&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - simpl. rewrite app_nil_r. reflexivity.&lt;br /&gt;
  - simpl. rewrite HI, app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 17. Demostrar que rev es involutiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall l : natlist,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite rev_app_distr. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 18. Demostrar que&lt;br /&gt;
      l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc4 : forall l1 l2 l3 l4 : natlist,&lt;br /&gt;
  l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3 l4. rewrite app_assoc. rewrite app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 19. Demostrar que al concatenar dos listas no aparecen ni&lt;br /&gt;
   desaparecen ceros. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma nonzeros_app : forall l1 l2 : natlist,&lt;br /&gt;
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 20. Definir la función&lt;br /&gt;
      beq_natlist : natlist -&amp;gt; natlist -&amp;gt; bool&lt;br /&gt;
   tal que (beq_natlist xs ys) se verifica si las listas xs e ys son&lt;br /&gt;
   iguales. Por ejemplo,&lt;br /&gt;
      beq_natlist nil nil         = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;4] = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_natlist (l1 l2 : natlist) : bool:=&lt;br /&gt;
  match l1, l2 with&lt;br /&gt;
  | nil,   nil   =&amp;gt; true&lt;br /&gt;
  | x::xs, y::ys =&amp;gt; beq_nat x y &amp;amp;&amp;amp; beq_natlist xs ys&lt;br /&gt;
  | _, _         =&amp;gt; false&lt;br /&gt;
 end.&lt;br /&gt;
&lt;br /&gt;
Example test_beq_natlist1: (beq_natlist nil nil = true).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist2: beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist3: beq_natlist [1;2;3] [1;2;4] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 21. Demostrar que la igualdad de listas cumple la propiedad&lt;br /&gt;
   reflexiva. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_natlist_refl : forall l:natlist,&lt;br /&gt;
  true = beq_natlist l l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|n xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- HI. replace (beq_nat n n) with true.  reflexivity.&lt;br /&gt;
    + rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 22. Demostrar que al incluir un elemento en un multiconjunto,&lt;br /&gt;
   ese elemento aparece al menos una vez en el resultado.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem count_member_nonzero : forall (s : bag),&lt;br /&gt;
  leb 1 (count 1 (1 :: s)) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
 intro s.  simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 23. Demostrar que cada número natural es menor o igual que&lt;br /&gt;
   su siguiente. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem ble_n_Sn : forall n,&lt;br /&gt;
  leb n (S n) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* 0 *)&lt;br /&gt;
    simpl.  reflexivity.&lt;br /&gt;
  - (* S n&amp;#039; *)&lt;br /&gt;
    simpl.  rewrite IHn&amp;#039;.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 24. Demostrar que al borrar una ocurrencia de 0 de un&lt;br /&gt;
   multiconjunto el número de ocurrencias de 0 en el resultado es menor&lt;br /&gt;
   o igual que en el original.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem remove_decreases_count: forall (s : bag),&lt;br /&gt;
  leb (count 0 (remove_one 0 s)) (count 0 s) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction s as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite ble_n_Sn. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.    &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 25. Escribir un teorema con las funciones count y sum de los&lt;br /&gt;
   multiconjuntos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_count_sum: forall n : nat, forall b1 b2 : bag,&lt;br /&gt;
  count n b1 + count n b2 = count n (sum b1 b2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n b1 b2. induction b1 as [|b bs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct (beq_nat b n).&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 26. Demostrar que la función rev es inyectiva; es decir,&lt;br /&gt;
      forall (l1 l2 : natlist), rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_injective : forall (l1 l2 : natlist),&lt;br /&gt;
  rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros. rewrite &amp;lt;- rev_involutive, &amp;lt;- H, rev_involutive. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Opcionales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_bad : natlist -&amp;gt; n -&amp;gt; nat&lt;br /&gt;
   tal que (nth_bad xs n) es el n-ésimo elemento de la lista xs y 42 si&lt;br /&gt;
   la lista tiene menos de n elementos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_bad (l:natlist) (n:nat) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; 42  (* un valor arbitrario *)&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; a&lt;br /&gt;
               | false =&amp;gt; nth_bad l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo natoption con los contructores&lt;br /&gt;
      Some : nat -&amp;gt; natoption&lt;br /&gt;
      None : natoption.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natoption : Type :=&lt;br /&gt;
  | Some : nat -&amp;gt; natoption&lt;br /&gt;
  | None : natoption.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_error : natlist -&amp;gt; nat -&amp;gt; natoption&lt;br /&gt;
   tal que (nth_error xs n) es el n-ésimo elemento de la lista xs o None&lt;br /&gt;
   si la lista tiene menos de n elementos. Por ejemplo,&lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
      nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; Some a&lt;br /&gt;
               | false =&amp;gt; nth_error l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* Introduciendo condicionales nos queda: *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error&amp;#039; (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O&lt;br /&gt;
               then Some a&lt;br /&gt;
               else nth_error&amp;#039; l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* Nota: Los condicionales funcionan sobre todo tipo inductivo con dos &lt;br /&gt;
   constructores en Coq, sin booleanos. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      option_elim nat -&amp;gt; natoption -&amp;gt; nat&lt;br /&gt;
   tal que (option_elim d o) es el valor de o, si o tienve valor o es d&lt;br /&gt;
   en caso contrario.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_elim (d : nat) (o : natoption) : nat :=&lt;br /&gt;
  match o with&lt;br /&gt;
  | Some n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  | None =&amp;gt; d&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 27. Definir la función&lt;br /&gt;
      hd_error : natlist -&amp;gt; natoption&lt;br /&gt;
   tal que (hd_error xs) es el primer elemento de xs, si xs es no vacía;&lt;br /&gt;
   o es None, en caso contrario. Por ejemplo,&lt;br /&gt;
      hd_error []    = None.&lt;br /&gt;
      hd_error [1]   = Some 1.&lt;br /&gt;
      hd_error [5;6] = Some 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error (l : natlist) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil   =&amp;gt; None&lt;br /&gt;
  | x::xs =&amp;gt; Some x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [] = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error2 : hd_error [1] = Some 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error3 : hd_error [5;6] = Some 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 28. Demostrar que&lt;br /&gt;
      hd default l = option_elim default (hd_error l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem option_elim_hd : forall (l:natlist) (default:nat),&lt;br /&gt;
  hd default l = option_elim default (hd_error l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l default. destruct l as [|x xs].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatList.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones parciales (o diccionarios)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo id con el constructor&lt;br /&gt;
      Id : nat -&amp;gt; id.&lt;br /&gt;
   La idea es usarlo como clave de los dicccionarios.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive id : Type :=&lt;br /&gt;
  | Id : nat -&amp;gt; id.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_id : id -&amp;gt; id -&amp;gt; bool&lt;br /&gt;
   tal que  (beq_id x1 x2) se verifcia si tienen la misma clave.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition beq_id (x1 x2 : id) :=&lt;br /&gt;
  match x1, x2 with&lt;br /&gt;
  | Id n1, Id n2 =&amp;gt; beq_nat n1 n2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 29. Demostrar que beq_id es reflexiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_id_refl : forall x, true = beq_id x x.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro x. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo PartialMap que importa a NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module PartialMap.&lt;br /&gt;
Export NatList.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo partial_map (para representar los&lt;br /&gt;
   diccionarios) con los contructores&lt;br /&gt;
      empty  : partial_map&lt;br /&gt;
      record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive partial_map : Type :=&lt;br /&gt;
  | empty  : partial_map&lt;br /&gt;
  | record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      update : partial_map -&amp;gt; id -&amp;gt; nat -&amp;gt; partial_map&lt;br /&gt;
   tal que (update d i v) es el diccionario obtenido a partir del d&lt;br /&gt;
   + si d tiene un elemento con clave i, le cambia su valor a v&lt;br /&gt;
   + en caso contrario, le añade el elemento v con clave i &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition update (d : partial_map)&lt;br /&gt;
                  (x : id) (value : nat)&lt;br /&gt;
                  : partial_map :=&lt;br /&gt;
  record x value d.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      find : id -&amp;gt; partial_map -&amp;gt; natoption &lt;br /&gt;
   tal que (find i d) es el valor de la entrada de d con clave i, o None&lt;br /&gt;
   si d no tiene ninguna entrada con clave i.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint find (x : id) (d : partial_map) : natoption :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | empty         =&amp;gt; None&lt;br /&gt;
  | record y v d&amp;#039; =&amp;gt; if beq_id x y&lt;br /&gt;
                     then Some v&lt;br /&gt;
                     else find x d&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 30. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
        find x (update d x v) = Some v.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_eq :&lt;br /&gt;
  forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
    find x (update d x v) = Some v.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x v. destruct d as [|d&amp;#039; x&amp;#039; v&amp;#039;].&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 31. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
        beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_neq :&lt;br /&gt;
  forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
    beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x y o p. simpl. rewrite p. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizr el módulo PartialMap&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End PartialMap.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 32. Se define el tipo baz por&lt;br /&gt;
      Inductive baz : Type :=&lt;br /&gt;
        | Baz1 : baz -&amp;gt; baz&lt;br /&gt;
        | Baz2 : baz -&amp;gt; bool -&amp;gt; baz.&lt;br /&gt;
   ¿Cuántos elementos tiene el tipo baz?&lt;br /&gt;
   ------------------------------------------------------------------ *)&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/SLC2018/index.php?title=Tema_2&amp;diff=120</id>
		<title>Tema 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_2&amp;diff=120"/>
		<updated>2018-07-15T10:57:03Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;coq&amp;quot;&amp;gt;&lt;br /&gt;
(* T2: Demostraciones por inducción en Coq *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de importación de teorías *)&lt;br /&gt;
Require Export T1_PF_en_Coq.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pruebas por inducción &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de demostración que no puede ser realizada por el método &lt;br /&gt;
   simple  *) &lt;br /&gt;
Theorem plus_n_O_firsttry : forall n:nat,&lt;br /&gt;
  n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  simpl. (* ¡¡¡No hace nada!!! *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem plus_n_O_secondtry : forall n:nat,&lt;br /&gt;
  n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n as [| n&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    reflexivity. (* Hasta aquí todo bien ... *)&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl.       (* ... pero otra vez no hacemos nada *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba por inducción de n = n + 0. *)&lt;br /&gt;
Theorem plus_n_O : forall n:nat, n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)    reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *) simpl. rewrite &amp;lt;- IHn&amp;#039;. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba por inducción de (minus n n = 0). *)&lt;br /&gt;
Theorem minus_diag : forall n,&lt;br /&gt;
  minus n n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    simpl. reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.1. Demostrar que &lt;br /&gt;
      forall n:nat, n * 0 = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_0_r : forall n:nat,&lt;br /&gt;
  n * 0 = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.2. Demostrar que &lt;br /&gt;
      forall n m : nat, S (n + m) = n + (S m).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_n_Sm : forall n m : nat,&lt;br /&gt;
  S (n + m) = n + (S m).&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.3. Demostrar que &lt;br /&gt;
      forall n m : nat, n + m = m + n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_comm : forall n m : nat,&lt;br /&gt;
  n + m = m + n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros  n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. rewrite &amp;lt;- plus_n_O. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite &amp;lt;- plus_n_Sm. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.4. Demostrar que &lt;br /&gt;
      forall n m p : nat, n + (m + p) = (n + m) + p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_assoc : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n m p. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
 -  reflexivity.&lt;br /&gt;
 -simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Se considera la siguiente función que dobla su argumento. &lt;br /&gt;
      Fixpoint double (n:nat) :=&lt;br /&gt;
        match n with&lt;br /&gt;
        | O =&amp;gt; O&lt;br /&gt;
        | S n&amp;#039; =&amp;gt; S (S (double n&amp;#039;))&lt;br /&gt;
        end.&lt;br /&gt;
&lt;br /&gt;
   Demostrar que &lt;br /&gt;
      forall n, double n = n + n. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint double (n:nat) :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; O&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; S (S (double n&amp;#039;))&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Lemma double_plus : forall n, double n = n + n .&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite plus_n_Sm. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Demostrar que&lt;br /&gt;
       forall n : nat, evenb (S n) = negb (evenb n).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem evenb_S : forall n : nat,&lt;br /&gt;
  evenb (S n) = negb (evenb n).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - rewrite IHn&amp;#039;. simpl. rewrite negb_involutive. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Explicar la diferencia entre las tácticas destruct e&lt;br /&gt;
   induction. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* La diferencia es que en la induct siempre tienes una hipótesis, a la&lt;br /&gt;
   que llamas hipótesis de inducción, así como dos únicos casos (el caso&lt;br /&gt;
   del elemento más simple y suponiendo que se cumple para n el de&lt;br /&gt;
   n+1). &lt;br /&gt;
&lt;br /&gt;
   En cambio, en destruct puedes tener mayor número de casos y no &lt;br /&gt;
   suponer una hipótesis.  *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Lemas locales &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de teorema con lema local usando assert. *)&lt;br /&gt;
Theorem mult_0_plus&amp;#039; : forall n m : nat,&lt;br /&gt;
  (0 + n) * m = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  assert (H: 0 + n = n). { reflexivity. }&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Otro ejemplo de teorema con lema local usando assert. &lt;br /&gt;
   Primero, la prueba si assert es *) &lt;br /&gt;
Theorem plus_rearrange_firsttry : forall n m p q : nat,&lt;br /&gt;
  (n + m) + (p + q) = (m + n) + (p + q).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p q.&lt;br /&gt;
  rewrite -&amp;gt; plus_comm.&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* En cambio usando assert *)&lt;br /&gt;
Theorem plus_rearrange : forall n m p q : nat,&lt;br /&gt;
  (n + m) + (p + q) = (m + n) + (p + q).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p q.&lt;br /&gt;
  assert (H: n + m = m + n).&lt;br /&gt;
  { rewrite -&amp;gt; plus_comm. reflexivity. }&lt;br /&gt;
  rewrite -&amp;gt; H. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pruebas formales vs pruebas informales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* &amp;quot;_Informal proofs are algorithms; formal proofs are code_.&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplos de pruebas formales en Coq *)&lt;br /&gt;
Theorem plus_assoc&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [| n&amp;#039; IHn&amp;#039;]. reflexivity.&lt;br /&gt;
  simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem plus_assoc&amp;#039;&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba informal &lt;br /&gt;
&lt;br /&gt;
   Theorem_: For any [n], [m] and [p],&lt;br /&gt;
      n + (m + p) = (n + m) + p.&lt;br /&gt;
&lt;br /&gt;
   Proof: By induction on [n].&lt;br /&gt;
    - First, suppose [n = 0].  We must show&lt;br /&gt;
         0 + (m + p) = (0 + m) + p.&lt;br /&gt;
      This follows directly from the definition of [+].&lt;br /&gt;
&lt;br /&gt;
    - Next, suppose [n = S n&amp;#039;], where&lt;br /&gt;
         n&amp;#039; + (m + p) = (n&amp;#039; + m) + p.&lt;br /&gt;
      We must show&lt;br /&gt;
         (S n&amp;#039;) + (m + p) = ((S n&amp;#039;) + m) + p.&lt;br /&gt;
&lt;br /&gt;
      By the definition of [+], this follows from&lt;br /&gt;
         S (n&amp;#039; + (m + p)) = S ((n&amp;#039; + m) + p),&lt;br /&gt;
      which is immediate from the induction hypothesis.  &lt;br /&gt;
&lt;br /&gt;
    Qed. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Escribir una prueba informal de que la suma es&lt;br /&gt;
   conmutativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Escribir prueba informal de&lt;br /&gt;
      forall n:nat, true = beq_nat n n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios complementarios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar, usando assert pero no induct,&lt;br /&gt;
      forall n m p : nat, n + (m + p) = m + (n + p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_swap : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = m + (n + p).&lt;br /&gt;
Proof. &lt;br /&gt;
  intros n m p. rewrite plus_assoc. rewrite plus_assoc.&lt;br /&gt;
  assert (H : n + m = m+n). {rewrite plus_comm. reflexivity. } &lt;br /&gt;
  rewrite H. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Demostrar que la multiplicación es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem one_id : forall n: nat,&lt;br /&gt;
    n = n*1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [|n IHn&amp;#039;].&lt;br /&gt;
  -reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem one_S : forall n : nat,&lt;br /&gt;
    S n = n+1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;-HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem mult_n_Sm : forall n m : nat, &lt;br /&gt;
    n * (m+1) = n*m+n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - rewrite &amp;lt;- plus_n_O. rewrite &amp;lt;- one_S. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite plus_swap. rewrite &amp;lt;- plus_assoc.&lt;br /&gt;
    rewrite one_S. rewrite &amp;lt;- one_S. rewrite plus_swap.&lt;br /&gt;
    rewrite plus_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem mult_comm : forall m n : nat,&lt;br /&gt;
  m * n = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
 -  rewrite mult_0_r. reflexivity.&lt;br /&gt;
 - simpl. rewrite HIn&amp;#039;. rewrite one_S. rewrite mult_n_Sm. rewrite plus_comm.&lt;br /&gt;
   reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.1. Demostrar que &lt;br /&gt;
      forall n:nat, true = leb n n.  &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem leb_refl : forall n:nat,&lt;br /&gt;
  true = leb n n.&lt;br /&gt;
Proof. intro n. induction n as [| n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - rewrite HIn&amp;#039;. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.2. Demostrar que &lt;br /&gt;
      forall n:nat, beq_nat 0 (S n) = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem zero_nbeq_S : forall n:nat,&lt;br /&gt;
  beq_nat 0 (S n) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.3. Demostrar que &lt;br /&gt;
      forall b : bool, andb b false = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem andb_false_r : forall b : bool,&lt;br /&gt;
  andb b false = false.&lt;br /&gt;
Proof. intros b. destruct b.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. reflexivity. &lt;br /&gt;
Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.4. Demostrar que &lt;br /&gt;
      forall n m p : nat, leb n m = true -&amp;gt; leb (p + n) (p + m) = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_ble_compat_l : forall n m p : nat,&lt;br /&gt;
  leb n m = true -&amp;gt; leb (p + n) (p + m) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p H. rewrite &amp;lt;- H. induction p as [|p&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.5. Demostrar que &lt;br /&gt;
      forall n:nat, beq_nat (S n) 0 = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem S_nbeq_0 : forall n:nat,&lt;br /&gt;
  beq_nat (S n) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.6. Demostrar que &lt;br /&gt;
       forall n:nat, 1 * n = n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_1_l : forall n:nat, 1 * n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. simpl. rewrite plus_n_O. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.7. Demostrar que &lt;br /&gt;
       forall b c : bool, orb (andb b c)&lt;br /&gt;
                              (orb (negb b)&lt;br /&gt;
                                   (negb c))&lt;br /&gt;
                          = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem all3_spec : forall b c : bool,&lt;br /&gt;
    orb&lt;br /&gt;
      (andb b c)&lt;br /&gt;
      (orb (negb b)&lt;br /&gt;
           (negb c))&lt;br /&gt;
    = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [].&lt;br /&gt;
  -  reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.8. Demostrar que &lt;br /&gt;
      forall n m p : nat, (n + m) * p = (n * p) + (m * p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_plus_distr_r : forall n m p : nat,&lt;br /&gt;
  (n + m) * p = (n * p) + (m * p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction p as [| p&amp;#039; HIp&amp;#039;].&lt;br /&gt;
  - rewrite -&amp;gt; mult_0_r. rewrite mult_0_r. rewrite mult_0_r. reflexivity.&lt;br /&gt;
  - rewrite one_S. rewrite mult_comm.&lt;br /&gt;
    rewrite mult_n_Sm. rewrite mult_n_Sm.&lt;br /&gt;
    rewrite plus_assoc. rewrite mult_comm.&lt;br /&gt;
    rewrite mult_n_Sm. rewrite HIp&amp;#039;.&lt;br /&gt;
    rewrite plus_swap. rewrite plus_assoc.&lt;br /&gt;
    rewrite plus_assoc. rewrite &amp;lt;- plus_assoc.&lt;br /&gt;
    rewrite plus_rearrange. rewrite plus_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.9. Demostrar que &lt;br /&gt;
      forall n m p : nat, n * (m * p) = (n * m) * p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_assoc : forall n m p : nat,&lt;br /&gt;
  n * (m * p) = (n * m) * p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. rewrite mult_plus_distr_r. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
       forall n : nat, true = beq_nat n n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem beq_nat_refl : forall n : nat,&lt;br /&gt;
  true = beq_nat n n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [| n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. La táctica replace permite especificar el subtérmino&lt;br /&gt;
   que se desea reescribir y su sustituto: [replace (t) with (u)]&lt;br /&gt;
   sustituye todas las copias de la expresión t en el objetivo por la&lt;br /&gt;
   expresión u y añade la ecuación (t = u) como un nuevo subojetivo. &lt;br /&gt;
 &lt;br /&gt;
   El uso de la táctica replace es especialmente útil cuando la táctica &lt;br /&gt;
   rewrite actúa sobre una parte del objetivo que no es la que se desea. &lt;br /&gt;
&lt;br /&gt;
   Demostrar, usando la táctica replace y sin usar &lt;br /&gt;
   [assert (n + m = m + n)], que&lt;br /&gt;
      forall n m p : nat, n + (m + p) = m + (n + p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_swap&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = m + (n + p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. rewrite plus_assoc. rewrite plus_assoc.&lt;br /&gt;
  replace (n+m) with (m+n). &lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - rewrite plus_comm. reflexivity.&lt;br /&gt;
Qed. &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/SLC2018/index.php?title=Tema_1&amp;diff=119</id>
		<title>Tema 1</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_1&amp;diff=119"/>
		<updated>2018-07-15T10:56:42Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;coq&amp;quot;&amp;gt;&lt;br /&gt;
(* T1: Programación funcional en Coq *)&lt;br /&gt;
&lt;br /&gt;
Definition admit {T: Type} : T.  Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Datos y funciones &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Tipos enumerados  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo day cuyos constructores sean los días de&lt;br /&gt;
   la semana.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive day : Type :=&lt;br /&gt;
  | monday    : day&lt;br /&gt;
  | tuesday   : day&lt;br /&gt;
  | wednesday : day&lt;br /&gt;
  | thursday  : day&lt;br /&gt;
  | friday    : day&lt;br /&gt;
  | saturday  : day&lt;br /&gt;
  | sunday    : day.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      next_weekday :: day -&amp;gt; day &lt;br /&gt;
   tal que (next_weekday d) es el día laboral siguiente a d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition next_weekday (d:day) : day :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | monday    =&amp;gt; tuesday&lt;br /&gt;
  | tuesday   =&amp;gt; wednesday&lt;br /&gt;
  | wednesday =&amp;gt; thursday&lt;br /&gt;
  | thursday  =&amp;gt; friday&lt;br /&gt;
  | friday    =&amp;gt; monday&lt;br /&gt;
  | saturday  =&amp;gt; monday&lt;br /&gt;
  | sunday    =&amp;gt; monday&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el valor de las siguientes expresiones &lt;br /&gt;
      + (next_weekday friday)&lt;br /&gt;
      + (next_weekday (next_weekday saturday))&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (next_weekday friday).&lt;br /&gt;
(* ==&amp;gt; monday : day *)&lt;br /&gt;
&lt;br /&gt;
Compute (next_weekday (next_weekday saturday)).&lt;br /&gt;
(* ==&amp;gt; tuesday : day *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
      (next_weekday (next_weekday saturday)) = tuesday&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_next_weekday:&lt;br /&gt;
  (next_weekday (next_weekday saturday)) = tuesday.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Booleanos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo bool cuyos constructores son true y false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive bool : Type :=&lt;br /&gt;
  | true  : bool&lt;br /&gt;
  | false : bool.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      negb :: bool -&amp;gt; bool&lt;br /&gt;
   tal que (negb b) es la negación de b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition negb (b:bool) : bool :=&lt;br /&gt;
  match b with&lt;br /&gt;
  | true  =&amp;gt; false&lt;br /&gt;
  | false =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      andb :: bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (andb b1 b2) es la conjunción de b1 y b2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition andb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true =&amp;gt; b2&lt;br /&gt;
  | false =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      orb :: bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (orb b1 b2) es la disyunción de b1 y b2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition orb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true  =&amp;gt; true&lt;br /&gt;
  | false =&amp;gt; b2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar las siguientes propiedades&lt;br /&gt;
      (orb true  false) = true.&lt;br /&gt;
      (orb false false) = false.&lt;br /&gt;
      (orb false true)  = true.&lt;br /&gt;
      (orb true  true)  = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_orb1: (orb true  false) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb2: (orb false false) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb3: (orb false true)  = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb4: (orb true  true)  = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir los operadores (&amp;amp;&amp;amp;) y (||) como abreviaturas de las&lt;br /&gt;
   funciones andb y orb.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x &amp;amp;&amp;amp; y&amp;quot; := (andb x y).&lt;br /&gt;
Notation &amp;quot;x || y&amp;quot; := (orb x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      false || false || true = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_orb5: false || false || true = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Definir la función &lt;br /&gt;
      nandb :: bool -&amp;gt; bool -&amp;gt; bool &lt;br /&gt;
   tal que (nanb x y) se verifica si x e y no son verdaderos.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades de nand&lt;br /&gt;
      (nandb true  false) = true.&lt;br /&gt;
      (nandb false false) = true.&lt;br /&gt;
      (nandb false true)  = true.&lt;br /&gt;
      (nandb true  true)  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition nandb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with &lt;br /&gt;
  | true  =&amp;gt; negb b2&lt;br /&gt;
  | false =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_nandb1: (nandb true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb2: (nandb false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb3: (nandb false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb4: (nandb true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb1 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true =&amp;gt; negb b2&lt;br /&gt;
  | _    =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb11: (nandb1 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb12: (nandb1 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb13: (nandb1 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb14: (nandb1 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb2 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1, b2 with&lt;br /&gt;
  | true, true =&amp;gt; false&lt;br /&gt;
  | _, _       =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb21: (nandb2 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb22: (nandb2 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb23: (nandb2 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb24: (nandb2 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb3 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  if b1 then negb b2 else true.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb31: (nandb3 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb32: (nandb3 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb33: (nandb3 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb34: (nandb3 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb4 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  negb (b1 &amp;amp;&amp;amp; b2).&lt;br /&gt;
&lt;br /&gt;
Example test_nandb41: (nandb4 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb42: (nandb4 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb43: (nandb4 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb44: (nandb4 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Definir la función&lt;br /&gt;
      andb3 :: bool -&amp;gt; bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (andb3 x y z) se verifica si x, y y z son verdaderos.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades de andb3&lt;br /&gt;
      (andb3 true  true  true)  = true.&lt;br /&gt;
      (andb3 false true  true)  = false.&lt;br /&gt;
      (andb3 true  false true)  = false.&lt;br /&gt;
      (andb3 true  true  false) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition andb3 (b1:bool) (b2:bool) (b3:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
   | true  =&amp;gt; andb b2 b3&lt;br /&gt;
   | false =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_andb31: (andb3 true true true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb32: (andb3 false true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb33: (andb3 true false true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb34: (andb3 true true false) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Notation &amp;quot;x &amp;amp;&amp;amp; y&amp;quot; := (andb x y).&lt;br /&gt;
&lt;br /&gt;
Definition andb32 (b1:bool) (b2:bool) (b3:bool) : bool :=&lt;br /&gt;
  b1 &amp;amp;&amp;amp; b2 &amp;amp;&amp;amp; b3.&lt;br /&gt;
&lt;br /&gt;
Example test_andb321: (andb32 true true true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb322: (andb32 false true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb323: (andb32 true false true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb324: (andb32 true true false) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Tipos de las funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de las siguientes expresiones&lt;br /&gt;
      + true&lt;br /&gt;
      + (negb true)&lt;br /&gt;
      + negb&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check true.&lt;br /&gt;
(* ===&amp;gt; true : bool *)&lt;br /&gt;
&lt;br /&gt;
Check (negb true).&lt;br /&gt;
(* ===&amp;gt; negb true : bool *)&lt;br /&gt;
&lt;br /&gt;
Check negb.&lt;br /&gt;
(* ===&amp;gt; negb : bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Tipos compuestos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo rgb cuyos constructores son red, green y&lt;br /&gt;
   blue. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive rgb : Type :=&lt;br /&gt;
  | red   : rgb&lt;br /&gt;
  | green : rgb&lt;br /&gt;
  | blue  : rgb.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo color cuyos constructores son black, white y&lt;br /&gt;
   primary, donde primary es una función de rgb en color.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive color : Type :=&lt;br /&gt;
  | black   : color&lt;br /&gt;
  | white   : color&lt;br /&gt;
  | primary : rgb -&amp;gt; color.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      monochrome :: color -&amp;gt; bool&lt;br /&gt;
   tal que (monochrome c) se verifica si c es monocromático.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition monochrome (c : color) : bool :=&lt;br /&gt;
  match c with&lt;br /&gt;
  | black     =&amp;gt; true&lt;br /&gt;
  | white     =&amp;gt; true&lt;br /&gt;
  | primary p =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      isred :: color -&amp;gt; bool&lt;br /&gt;
   tal que (isred c) se verifica si c es rojo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition isred (c : color) : bool :=&lt;br /&gt;
  match c with&lt;br /&gt;
  | black       =&amp;gt; false&lt;br /&gt;
  | white       =&amp;gt; false&lt;br /&gt;
  | primary red =&amp;gt; true&lt;br /&gt;
  | primary _   =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Módulos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Iniciar el módulo NatPlayground.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatPlayground.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Números naturales  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo nat de los números naturales con los&lt;br /&gt;
   constructores 0 (para el 0) y S (para el siguiente).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Inductive nat : Type :=&lt;br /&gt;
  | O : nat&lt;br /&gt;
  | S : nat -&amp;gt; nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      pred :: nat -&amp;gt; nat&lt;br /&gt;
   tal que (pred n) es el predecesor de n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Definition pred (n : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; O&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Finaliz el módulo NatPlayground.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatPlayground.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo y valor de la expresión (S (S (S (S O)))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (S (S (S (S O)))).&lt;br /&gt;
  (* ===&amp;gt; 4 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      minustwo :: nat -&amp;gt; nat&lt;br /&gt;
   tal que (minustwo n) es n-2. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition minustwo (n : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O        =&amp;gt; O&lt;br /&gt;
    | S O      =&amp;gt; O&lt;br /&gt;
    | S (S n&amp;#039;) =&amp;gt; n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión (minustwo 4).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (minustwo 4).&lt;br /&gt;
  (* ===&amp;gt; 2 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular et tipo de las funcionse S, pred y minustwo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check S.&lt;br /&gt;
Check pred.&lt;br /&gt;
Check minustwo.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      evenb :: nat -&amp;gt; bool&lt;br /&gt;
   tal que (evenb n) se verifica si n es par.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint evenb (n:nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O        =&amp;gt; true&lt;br /&gt;
  | S O      =&amp;gt; false&lt;br /&gt;
  | S (S n&amp;#039;) =&amp;gt; evenb n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      oddb :: nat -&amp;gt; bool&lt;br /&gt;
   tal que (oddb n) se verifica si n es impar.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition oddb (n:nat) : bool   :=   negb (evenb n).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      + oddb 1 = true.&lt;br /&gt;
      + oddb 4 = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_oddb1: oddb 1 = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_oddb2: oddb 4 = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Iniciar el módulo NatPlayground2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatPlayground2.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus 3 2 = 5&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint plus (n : nat) (m : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; m&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; S (plus n&amp;#039; m)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Compute (plus 3 2).&lt;br /&gt;
(* ===&amp;gt; 5: nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      mult :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult 3 2 = 6&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint mult (n m : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; O&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; plus m (mult n&amp;#039; m)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_mult1: (mult 2 3) = 6.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      minus :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (minus n m) es la diferencia de n y m. Por ejemplo,&lt;br /&gt;
      mult 3 2 = 1&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint minus (n m:nat) : nat :=&lt;br /&gt;
  match (n, m) with&lt;br /&gt;
  | (O   , _)    =&amp;gt; O&lt;br /&gt;
  | (S _ , O)    =&amp;gt; n&lt;br /&gt;
  | (S n&amp;#039;, S m&amp;#039;) =&amp;gt; minus n&amp;#039; m&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Cerrar el módulo NatPlayground2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatPlayground2.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      exp : nat -&amp;gt;  nat -&amp;gt; nat&lt;br /&gt;
   tal que (exp x n) es la potencia n-ésima de x. Por ejemplo,&lt;br /&gt;
      exp 2 3 = 8&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint exp (base power : nat) : nat :=&lt;br /&gt;
  match power with&lt;br /&gt;
    | O   =&amp;gt; S O&lt;br /&gt;
    | S p =&amp;gt; mult base (exp base p)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Compute (exp 2 3).&lt;br /&gt;
(* ===&amp;gt; 8 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      factorial :: nat -&amp;gt; nat1&lt;br /&gt;
   tal que (factorial n) es el factorial de n. &lt;br /&gt;
&lt;br /&gt;
      (factorial 3) = 6.&lt;br /&gt;
      (factorial 5) = (mult 10 12).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5, angruicam1 *)&lt;br /&gt;
Fixpoint factorial (n:nat) : nat := &lt;br /&gt;
  match n with&lt;br /&gt;
  | O    =&amp;gt; 1&lt;br /&gt;
  | S n&amp;#039; =&amp;gt;  S n&amp;#039; * factorial n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_factorial1: (factorial 3) = 6.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_factorial2: (factorial 5) = (mult 10 12).&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir los operadores +, - y * como abreviaturas de  las&lt;br /&gt;
   funciones plus, minus y mult.  &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x + y&amp;quot; := (plus x y)&lt;br /&gt;
                       (at level 50, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
Notation &amp;quot;x - y&amp;quot; := (minus x y)&lt;br /&gt;
                       (at level 50, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
Notation &amp;quot;x * y&amp;quot; := (mult x y)&lt;br /&gt;
                       (at level 40, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_nat : nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (beq_nat n m) se verifica si n y me son iguales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_nat (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; match m with&lt;br /&gt;
         | O    =&amp;gt; true&lt;br /&gt;
         | S m&amp;#039; =&amp;gt; false&lt;br /&gt;
         end&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; match m with&lt;br /&gt;
            | O    =&amp;gt; false&lt;br /&gt;
            | S m&amp;#039; =&amp;gt; beq_nat n&amp;#039; m&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      leb : nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (leb n m) se verifica si n es menor o igual que m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint leb (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O    =&amp;gt; true&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; match m with&lt;br /&gt;
            | O    =&amp;gt; false&lt;br /&gt;
            | S m&amp;#039; =&amp;gt; leb n&amp;#039; m&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar las siguientes propiedades&lt;br /&gt;
      + (leb 2 2) = true.&lt;br /&gt;
      + (leb 2 4) = true.&lt;br /&gt;
      + (leb 4 2) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_leb1: (leb 2 2) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_leb2: (leb 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_leb3: (leb 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      blt_nat :: nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (blt n m) se verifica si n es menor que m.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades&lt;br /&gt;
      (blt_nat 2 2) = false.&lt;br /&gt;
      (blt_nat 2 4) = true.&lt;br /&gt;
      (blt_nat 4 2) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition blt_nat (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; true&lt;br /&gt;
  | S n&amp;#039; =&amp;gt;&lt;br /&gt;
      match m with&lt;br /&gt;
      | O    =&amp;gt; false&lt;br /&gt;
      | S m&amp;#039; =&amp;gt; leb (S n&amp;#039;)  m&amp;#039;&lt;br /&gt;
      end&lt;br /&gt;
  end.                                   &lt;br /&gt;
&lt;br /&gt;
Example prop_blt_nat1: (blt_nat 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_blt_nat2: (blt_nat 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_blt_nat3: (blt_nat 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition blt_nat2 (n m : nat) : bool :=&lt;br /&gt;
  negb (beq_nat (m-n) 0).&lt;br /&gt;
&lt;br /&gt;
Example test_blt_nat21: (blt_nat2 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_blt_nat22: (blt_nat2 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_blt_nat23: (blt_nat2 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por simplificación &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que el 0 es el elemento neutro por la izquierda de&lt;br /&gt;
   la suma de los números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración *)&lt;br /&gt;
Theorem plus_O_n : forall n : nat, 0 + n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración *)&lt;br /&gt;
Theorem plus_O_n&amp;#039; : forall n : nat, 0 + n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la suma de 1 y n es el siguiente de n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_1_l : forall n:nat, 1 + n = S n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que el producto de 0 por n es 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem mult_0_l : forall n:nat, 0 * n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por reescritura &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que si n = m, entonces n + n = m + m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Theorem plus_id_example : forall n m:nat,&lt;br /&gt;
  n = m -&amp;gt;&lt;br /&gt;
  n + n = m + m.&lt;br /&gt;
&lt;br /&gt;
Proof.&lt;br /&gt;
  (* move both quantifiers into the context: *)&lt;br /&gt;
  intros n m.&lt;br /&gt;
  (* move the hypothesis into the context: *)&lt;br /&gt;
  intros H.&lt;br /&gt;
  (* rewrite the goal using the hypothesis: *)&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Demostrar que si n = m y m = o, entonces n + m = m + o.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_id_exercise: forall n m o : nat,&lt;br /&gt;
  n = m -&amp;gt; m = o -&amp;gt; n + m = m + o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  intros o Ho.&lt;br /&gt;
  rewrite -&amp;gt; Ho.&lt;br /&gt;
  intros H.&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem plus_id_exercise2 : forall n m o : nat,&lt;br /&gt;
  n = m -&amp;gt; m = o -&amp;gt; n + m = m + o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o H1 H2.&lt;br /&gt;
  rewrite -&amp;gt; H1.&lt;br /&gt;
  rewrite -&amp;gt; H2.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que (0 + n) * m = n * m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem mult_0_plus : forall n m : nat,&lt;br /&gt;
  (0 + n) * m = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  rewrite -&amp;gt; plus_O_n.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar que si m = S n, entonces m * (1 + n) = m * m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_S_1 : forall n m : nat,&lt;br /&gt;
  m = S n -&amp;gt;&lt;br /&gt;
  m * (1 + n) = m * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  intros H.&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem mult_S_12 : forall n m : nat,&lt;br /&gt;
  m = S n -&amp;gt;&lt;br /&gt;
  m * (1 + n) = m * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  rewrite H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por análisis de casos &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que n + 1 es distinto de 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1º intento *)&lt;br /&gt;
Theorem plus_1_neq_0_firsttry : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  simpl.  (* does nothing! *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* 2º intento *)&lt;br /&gt;
Theorem plus_1_neq_0 : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n as [| n&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la negación es involutiva; es decir, la&lt;br /&gt;
   negación de la negación de b es b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem negb_involutive : forall b : bool,&lt;br /&gt;
  negb (negb b) = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b. destruct b.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración *)&lt;br /&gt;
Theorem andb_commutative : forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración *)&lt;br /&gt;
Theorem andb_commutative&amp;#039; : forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  { destruct c.&lt;br /&gt;
    { reflexivity. }&lt;br /&gt;
    { reflexivity. } }&lt;br /&gt;
  { destruct c.&lt;br /&gt;
    { reflexivity. }&lt;br /&gt;
    { reflexivity. } }&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem andb3_exchange :&lt;br /&gt;
  forall b c d, andb (andb b c) d = andb (andb b d) c.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c d. destruct b.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que n + 1 es distinto de 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_1_neq_0&amp;#039; : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [|n].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem andb_commutative&amp;#039;&amp;#039; :&lt;br /&gt;
  forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que si andb b c = true, entonces c = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem andb_true_elim2 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  - intros H. rewrite &amp;lt;-H. reflexivity.&lt;br /&gt;
  - intros H. rewrite &amp;lt;-H. destruct false.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + destruct c. rewrite &amp;lt;-H. reflexivity. reflexivity. &lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem andb_true_elim22 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [] [].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* jorcatote *)&lt;br /&gt;
Theorem andb_true_elim23 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct c.&lt;br /&gt;
    - reflexivity.   &lt;br /&gt;
    - destruct b.&lt;br /&gt;
      + simpl. intros h. rewrite h. reflexivity.&lt;br /&gt;
      + simpl. intros h. rewrite h. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Dmostrar que 0 es distinto de n + 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem zero_nbeq_plus_1: forall n : nat,&lt;br /&gt;
  beq_nat 0 (n + 1) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem zero_nbeq_plus_12 : forall n : nat,&lt;br /&gt;
  beq_nat 0 (n + 1) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [| n&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios complementarios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Demostrar que&lt;br /&gt;
      forall (f : bool -&amp;gt; bool),&lt;br /&gt;
        (forall (x : bool), f x = x) -&amp;gt; &lt;br /&gt;
        forall (b : bool), f (f b) = b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1, alerodrod5 *)&lt;br /&gt;
Theorem identity_fn_applied_twice :&lt;br /&gt;
  forall (f : bool -&amp;gt; bool),&lt;br /&gt;
  (forall (x : bool), f x = x) -&amp;gt;&lt;br /&gt;
  forall (b : bool), f (f b) = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros f x b.&lt;br /&gt;
  rewrite x.&lt;br /&gt;
  rewrite x.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
      forall (b c : bool),&lt;br /&gt;
        (andb b c = orb b c) -&amp;gt; b = c.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 alerodrod5 *)&lt;br /&gt;
Theorem andb_eq_orb :&lt;br /&gt;
  forall (b c : bool),&lt;br /&gt;
  (andb b c = orb b c) -&amp;gt;&lt;br /&gt;
  b = c.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] c.&lt;br /&gt;
  - simpl. intros H. rewrite H. reflexivity.&lt;br /&gt;
  - simpl. intros H. rewrite H. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. En este ejercicio se considera la siguiente&lt;br /&gt;
   representación de los números naturales&lt;br /&gt;
      Inductive nat2 : Type :=&lt;br /&gt;
        | C  : nat2&lt;br /&gt;
        | D  : nat2 -&amp;gt; nat2&lt;br /&gt;
        | SD : nat2 -&amp;gt; nat2.&lt;br /&gt;
   donde C representa el cero, D el doble y SD el siguiente del doble.&lt;br /&gt;
&lt;br /&gt;
   Definir la función&lt;br /&gt;
      nat2Anat :: nat2 -&amp;gt; nat&lt;br /&gt;
   tal que (nat2Anat x) es el número natural representado por x. &lt;br /&gt;
&lt;br /&gt;
   Demostrar que &lt;br /&gt;
      nat2Anat (SD (SD C))     = 3&lt;br /&gt;
      nat2Anat (D (SD (SD C))) = 6.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1, alerodrod5 *)&lt;br /&gt;
Inductive nat2 : Type :=&lt;br /&gt;
  | C  : nat2&lt;br /&gt;
  | D  : nat2 -&amp;gt; nat2&lt;br /&gt;
  | SD : nat2 -&amp;gt; nat2.&lt;br /&gt;
 &lt;br /&gt;
Fixpoint nat2Anat (x:nat2) : nat :=&lt;br /&gt;
  match x with&lt;br /&gt;
  | C =&amp;gt; O&lt;br /&gt;
  | D n =&amp;gt; 2*nat2Anat n&lt;br /&gt;
  | SD n =&amp;gt; (2*nat2Anat n)+1&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example prop_nat2Anat1: (nat2Anat (SD (SD C))) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example prop_nat2Anat2: (nat2Anat (D (SD (SD C)))) = 6.&lt;br /&gt;
Proof. reflexivity. Qed.&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/SLC2018/index.php?title=SLC2018:_Seminario_de_L%C3%B3gica_Computacional_(2018)&amp;diff=118</id>
		<title>SLC2018: Seminario de Lógica Computacional (2018)</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=SLC2018:_Seminario_de_L%C3%B3gica_Computacional_(2018)&amp;diff=118"/>
		<updated>2018-07-15T10:54:10Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Página creada con «== Material para el seminario == * Temas: Teorías de los temas (incluyendo los ejercicios). * Documentación: Lecturas recomendadas. * Sistemas: Sistemas utili…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material para el seminario ==&lt;br /&gt;
* [[Temas]]: Teorías de los temas (incluyendo los ejercicios).&lt;br /&gt;
* [[Documentación]]: Lecturas recomendadas.&lt;br /&gt;
* [[Sistemas]]: Sistemas utilizados.&lt;br /&gt;
* [https://tarski.cs.us.es/~jalonso/vestigium/tag/slc2018 Diario]: Descripción diaria de las sesiones.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=MediaWiki:Common.css&amp;diff=117</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=MediaWiki:Common.css&amp;diff=117"/>
		<updated>2018-07-15T10:51:01Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Página creada con «/* Los estilos CSS colocados aquí se aplicarán a todas las apariencias */ @import url(&amp;quot;/~jalonso/font-awesome-4.7.0/css/font-awesome.min.css&amp;quot;);»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Los estilos CSS colocados aquí se aplicarán a todas las apariencias */&lt;br /&gt;
@import url(&amp;quot;/~jalonso/font-awesome-4.7.0/css/font-awesome.min.css&amp;quot;);&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=113</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=113"/>
		<updated>2018-05-06T09:12:06Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Programación funcional en Coq] ([[Tema 1 | Código]]).&lt;br /&gt;
** Tema 2: [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Demostraciones por inducción en Coq] ([[Tema 2 | Código]]).&lt;br /&gt;
** Tema 3: [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Datos estructurados en Coq] ([[Tema 3 | Código]]).&lt;br /&gt;
** Tema 4: [https://softwarefoundations.cis.upenn.edu/lf-current/Poly.html Polimorfismo y orden superior en Coq] ([[Tema 4 | Código]]).&lt;br /&gt;
** Tema 5: [https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html Tácticas básicas] ([[Tema 5 | Código]]).&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
** Miriam Medrán Navarro (Tema 4).&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=112</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=112"/>
		<updated>2018-05-06T09:10:41Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Programación funcional en Coq]] ([[Tema 1 | Código]]).&lt;br /&gt;
** Tema 2: [[https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Demostraciones por inducción en Coq ([[Tema 2 | Código]]).&lt;br /&gt;
** Tema 3: [[https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Datos estructurados en Coq]] ([[Tema 3 | Código]]).&lt;br /&gt;
** Tema 4: [[https://softwarefoundations.cis.upenn.edu/lf-current/Poly.html Polimorfismo y orden superior en Coq]] ([[Tema 4 | Código]]).&lt;br /&gt;
** Tema 5: [[https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html Tácticas básicas]] ([[Tema 5 | Código]]).&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
** Miriam Medrán Navarro (Tema 4).&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=111</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=111"/>
		<updated>2018-05-06T09:08:52Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html | Programación funcional en Coq]] ([[Tema 1 | Código]]).&lt;br /&gt;
** Tema 2: [[https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html | Demostraciones por inducción en Coq ([[Tema 2 | Código]]).&lt;br /&gt;
** Tema 3: [[https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html | Datos estructurados en Coq]] ([[Tema 3 | Código]]).&lt;br /&gt;
** Tema 4: [[https://softwarefoundations.cis.upenn.edu/lf-current/Poly.html | Polimorfismo y orden superior en Coq]] ([[Tema 4 | Código]]).&lt;br /&gt;
** Tema 5: [[https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html | Tácticas básicas]] ([[Tema 5 | Código]]).&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
** Miriam Medrán Navarro (Tema 4).&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_5&amp;diff=110</id>
		<title>Tema 5</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_5&amp;diff=110"/>
		<updated>2018-05-06T09:00:29Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Página creada con &amp;#039;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; (* T5: Tácticas básicas *)  Require Export T4_PolimorfismoyOS.  (* =====================================================================    § La táctic...&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T5: Tácticas básicas *)&lt;br /&gt;
&lt;br /&gt;
Require Export T4_PolimorfismoyOS.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § La táctica apply&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración donde el objetivo coincide con alguna&lt;br /&gt;
   hipótesis. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* Demostración sin apply *)&lt;br /&gt;
Theorem silly1 : forall (n m o p : nat),&lt;br /&gt;
    n = m  -&amp;gt;&lt;br /&gt;
    [n;o] = [n;p] -&amp;gt;&lt;br /&gt;
    [n;o] = [m;p].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p eq1 eq2.&lt;br /&gt;
  (* [n; o] = [m; p] *)&lt;br /&gt;
  rewrite &amp;lt;- eq1.&lt;br /&gt;
  (* [n; o] = [n; p] *)&lt;br /&gt;
  rewrite eq2.&lt;br /&gt;
  (* [n; p] = [n; p] *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Demostración con apply *)&lt;br /&gt;
Theorem silly1&amp;#039; : forall (n m o p : nat),&lt;br /&gt;
    n = m  -&amp;gt;&lt;br /&gt;
    [n;o] = [n;p] -&amp;gt;&lt;br /&gt;
    [n;o] = [m;p].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p eq1 eq2.&lt;br /&gt;
  (* [n; o] = [m; p] *)&lt;br /&gt;
  rewrite &amp;lt;- eq1.&lt;br /&gt;
  (* [n; o] = [n; p] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de aplicación de apply con hipótesis condicionales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly2 : forall (n m o p : nat),&lt;br /&gt;
    n = m  -&amp;gt;&lt;br /&gt;
    (forall (q r : nat), q = r -&amp;gt; [q;o] = [r;p]) -&amp;gt;&lt;br /&gt;
    [n;o] = [m;p].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o p eq1 eq2.&lt;br /&gt;
  (* [n; o] = [m; p] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
  (* n = m *)&lt;br /&gt;
  apply eq1.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de aplicación de apply con hipótesis condicionales y&lt;br /&gt;
   cuantificadores. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly2a : forall (n m : nat),&lt;br /&gt;
    (n,n) = (m,m)  -&amp;gt;&lt;br /&gt;
    (forall (q r : nat), (q,q) = (r,r) -&amp;gt; [q] = [r]) -&amp;gt;&lt;br /&gt;
    [n] = [m].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m eq1 eq2.&lt;br /&gt;
  (* [n] = [m] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
  (* (n, n) = (m, m) *)&lt;br /&gt;
  apply eq1.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Demostrar, sin usar simpl, que&lt;br /&gt;
      (forall n, evenb n = true -&amp;gt; oddb (S n) = true) -&amp;gt;&lt;br /&gt;
      evenb 3 = true -&amp;gt;&lt;br /&gt;
      oddb 4 = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly_ex :&lt;br /&gt;
  (forall n, evenb n = true -&amp;gt; oddb (S n) = true) -&amp;gt;&lt;br /&gt;
  evenb 3 = true -&amp;gt;&lt;br /&gt;
  oddb 4 = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo e necesidad de usar symmetry antes de apply.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly3_firsttry : forall (n : nat),&lt;br /&gt;
    true = beq_nat n 5  -&amp;gt;&lt;br /&gt;
    beq_nat (S (S n)) 7 = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n H.&lt;br /&gt;
  (* beq_nat (S (S n)) 7 = true *)&lt;br /&gt;
  symmetry.&lt;br /&gt;
  (* true = beq_nat (S (S n)) 7 *)&lt;br /&gt;
  simpl.&lt;br /&gt;
  (* true = beq_nat n 5 *)&lt;br /&gt;
  apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Demostrar&lt;br /&gt;
      forall (l l&amp;#039; : list nat), l = rev l&amp;#039; -&amp;gt; l&amp;#039; = rev l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_exercise1:&lt;br /&gt;
  forall (l l&amp;#039; : list nat), l = rev l&amp;#039; -&amp;gt; l&amp;#039; = rev l.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § La táctica apply ... with ...&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Con dos reescrituras.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_example : forall (a b c d e f : nat),&lt;br /&gt;
    [a;b] = [c;d] -&amp;gt;&lt;br /&gt;
    [c;d] = [e;f] -&amp;gt;&lt;br /&gt;
    [a;b] = [e;f].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros a b c d e f eq1 eq2.&lt;br /&gt;
  (* [a; b] = [e; f] *)&lt;br /&gt;
  rewrite -&amp;gt; eq1.&lt;br /&gt;
  (* [c; d] = [e; f] *)&lt;br /&gt;
  rewrite -&amp;gt; eq2.&lt;br /&gt;
  (* [e; f] = [e; f] *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de lema para simplificar la demostración anterior.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem trans_eq : forall (X:Type) (n m o : X),&lt;br /&gt;
    n = m -&amp;gt; m = o -&amp;gt; n = o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X n m o eq1 eq2.&lt;br /&gt;
  (* n = o *)&lt;br /&gt;
  rewrite -&amp;gt; eq1.&lt;br /&gt;
  (* m = o *)&lt;br /&gt;
  rewrite -&amp;gt; eq2.&lt;br /&gt;
  (* o = o *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. De simplificación de la prueba usando el lema.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_example&amp;#039; : forall (a b c d e f : nat),&lt;br /&gt;
    [a;b] = [c;d] -&amp;gt;&lt;br /&gt;
    [c;d] = [e;f] -&amp;gt;&lt;br /&gt;
    [a;b] = [e;f].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros a b c d e f eq1 eq2.&lt;br /&gt;
  (* [a; b] = [e; f] *)&lt;br /&gt;
  apply trans_eq with (m:=[c;d]).&lt;br /&gt;
  (* [a; b] = [c; d]&lt;br /&gt;
     [c; d] = [e; f] *) &lt;br /&gt;
  apply eq1.&lt;br /&gt;
  (* [c; d] = [e; f] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Simplificación de la prueba anterior.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_example&amp;#039;&amp;#039; : forall (a b c d e f : nat),&lt;br /&gt;
    [a;b] = [c;d] -&amp;gt;&lt;br /&gt;
    [c;d] = [e;f] -&amp;gt;&lt;br /&gt;
    [a;b] = [e;f].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros a b c d e f eq1 eq2.&lt;br /&gt;
  (* [a; b] = [e; f] *)&lt;br /&gt;
  apply trans_eq with [c;d].&lt;br /&gt;
  (* [a; b] = [c; d]&lt;br /&gt;
     [c; d] = [e; f] *) &lt;br /&gt;
  apply eq1.&lt;br /&gt;
  (* [c; d] = [e; f] *)&lt;br /&gt;
  apply eq2.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Demostrar que&lt;br /&gt;
      forall (n m o p : nat),&lt;br /&gt;
        m = (minustwo o) -&amp;gt;&lt;br /&gt;
        (n + p) = m -&amp;gt;&lt;br /&gt;
        (n + p) = (minustwo o).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example trans_eq_exercise : forall (n m o p : nat),&lt;br /&gt;
     m = (minustwo o) -&amp;gt;&lt;br /&gt;
     (n + p) = m -&amp;gt;&lt;br /&gt;
     (n + p) = (minustwo o).&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § La táctica inversión&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración con inversión sobre los naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem S_injective : forall (n m : nat),&lt;br /&gt;
  S n = S m -&amp;gt;&lt;br /&gt;
  n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  (* n : nat&lt;br /&gt;
     m : nat&lt;br /&gt;
     H : S n = S m *) &lt;br /&gt;
  inversion H.&lt;br /&gt;
  (* H1 : n = m *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de inversión generando varias hipótesis.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex1 : forall (n m o : nat),&lt;br /&gt;
    [n; m] = [o; o] -&amp;gt;&lt;br /&gt;
    [n] = [m].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o H.&lt;br /&gt;
  (* n : nat&lt;br /&gt;
     m : nat&lt;br /&gt;
     o : nat&lt;br /&gt;
     H : [n; m] = [o; o] *)&lt;br /&gt;
  inversion H.&lt;br /&gt;
  (* H1 : n = o&lt;br /&gt;
     H2 : m = o *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de nombramiento de las hipótesis generadas por inversión.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex2 : forall (n m : nat),&lt;br /&gt;
    [n] = [m] -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  (* n : nat&lt;br /&gt;
     m : nat&lt;br /&gt;
     H : [n] = [m] *)&lt;br /&gt;
  inversion H as [Hnm].&lt;br /&gt;
  (* Hnm : n = m *)&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Demostrar que&lt;br /&gt;
      forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
        x :: y :: l = z :: j -&amp;gt;&lt;br /&gt;
        y :: l = x :: j -&amp;gt;&lt;br /&gt;
        x = y.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example inversion_ex3 : forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
  x :: y :: l = z :: j -&amp;gt;&lt;br /&gt;
  y :: l = x :: j -&amp;gt;&lt;br /&gt;
  x = y.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración por inversión basada en que los constructores&lt;br /&gt;
   son disjuntos.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_nat_0_l : forall n,&lt;br /&gt;
    beq_nat 0 n = true -&amp;gt; n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  (* beq_nat 0 n = true -&amp;gt; n = 0 *)&lt;br /&gt;
  destruct n as [| n&amp;#039;].&lt;br /&gt;
  - (* beq_nat 0 0 = true -&amp;gt; 0 = 0 *)&lt;br /&gt;
    intros H.&lt;br /&gt;
    (* 0 = 0 *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* beq_nat 0 (S n&amp;#039;) = true -&amp;gt; S n&amp;#039; = 0 *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* false = true -&amp;gt; S n&amp;#039; = 0 *)&lt;br /&gt;
    intros H.&lt;br /&gt;
    (* S n&amp;#039; = 0 *)&lt;br /&gt;
    inversion H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplos de demostración por inversión sobre los booleanos.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex4 : forall (n : nat),&lt;br /&gt;
    S n = O -&amp;gt;&lt;br /&gt;
    2 + 2 = 5.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n contra.&lt;br /&gt;
  inversion contra.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem inversion_ex5 : forall (n m : nat),&lt;br /&gt;
    false = true -&amp;gt;&lt;br /&gt;
    [n] = [m].&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m contra.&lt;br /&gt;
  inversion contra.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Demostrar que&lt;br /&gt;
      forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
        x :: y :: l = [] -&amp;gt;&lt;br /&gt;
        y :: l = z :: j -&amp;gt;&lt;br /&gt;
        x = z.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example inversion_ex6 :&lt;br /&gt;
  forall (X : Type) (x y z : X) (l j : list X),&lt;br /&gt;
    x :: y :: l = [] -&amp;gt;&lt;br /&gt;
    y :: l = z :: j -&amp;gt;&lt;br /&gt;
    x = z.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de lema que usaremos más tarde.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem f_equal : forall (A B : Type) (f: A -&amp;gt; B) (x y: A),&lt;br /&gt;
    x = y -&amp;gt; f x = f y.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros A B f x y eq.&lt;br /&gt;
  rewrite eq.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Uso de tácticas sobre las hipótesis&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de demostración con &amp;quot;simpl in ...&amp;quot;&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem S_inj : forall (n m : nat) (b : bool),&lt;br /&gt;
    beq_nat (S n) (S m) = b  -&amp;gt;&lt;br /&gt;
    beq_nat n m = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m b H.&lt;br /&gt;
  (* H : beq_nat (S n) (S m) = b *)&lt;br /&gt;
  simpl in H.&lt;br /&gt;
  (* H : beq_nat n m = b *)&lt;br /&gt;
  apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de &amp;quot;razonamiento hacia adelante&amp;quot; con &amp;quot;apply L in H&amp;quot;.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem silly3&amp;#039; : forall (n : nat),&lt;br /&gt;
  (beq_nat n 5 = true -&amp;gt; beq_nat (S (S n)) 7 = true) -&amp;gt;&lt;br /&gt;
  true = beq_nat n 5  -&amp;gt;&lt;br /&gt;
  true = beq_nat (S (S n)) 7.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n eq H.&lt;br /&gt;
  (* eq : beq_nat n 5 = true -&amp;gt; beq_nat (S (S n)) 7 = true&lt;br /&gt;
     H : true = beq_nat n 5 *)&lt;br /&gt;
  symmetry in H.&lt;br /&gt;
  (* H : beq_nat n 5 = true *)&lt;br /&gt;
  apply eq in H.&lt;br /&gt;
  (* H : beq_nat (S (S n)) 7 = true *)&lt;br /&gt;
  symmetry in H.&lt;br /&gt;
  (* H : true = beq_nat (S (S n)) 7 *)&lt;br /&gt;
  apply H.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar&lt;br /&gt;
      forall n m,&lt;br /&gt;
        n + n = m + m -&amp;gt;&lt;br /&gt;
        n = m.&lt;br /&gt;
&lt;br /&gt;
   Nota: Usar plus_n_Sm&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_n_n_injective :&lt;br /&gt;
  forall n m,&lt;br /&gt;
    n + n = m + m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  induction n as [| n&amp;#039;].&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Control de la hipótesis de inducción  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de necesidad de controlar la hipótesis de inducción.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem double_injective_FAILED : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  induction n as [| n&amp;#039;].&lt;br /&gt;
  - (* double 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    intros eq.&lt;br /&gt;
    (* 0 = m *)&lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* 0 = O *)&lt;br /&gt;
      reflexivity.&lt;br /&gt;
    + (* 0 = S m&amp;#039; *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
  - (* double (S n&amp;#039;) = double m -&amp;gt; S n&amp;#039; = m *)&lt;br /&gt;
    intros eq.&lt;br /&gt;
    (* S n&amp;#039; = m *) &lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* S n&amp;#039; = 0 *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
    + (* S n&amp;#039; = S m&amp;#039; *)&lt;br /&gt;
      apply f_equal.&lt;br /&gt;
      (* n&amp;#039; = m&amp;#039; *)&lt;br /&gt;
      Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem double_injective : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  induction n as [| n&amp;#039;].&lt;br /&gt;
  - (* forall m : nat, double 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* forall m : nat, 0 = double m -&amp;gt; 0 = m *)&lt;br /&gt;
    intros m eq.&lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* 0 = O *)&lt;br /&gt;
      reflexivity.&lt;br /&gt;
    + (* 0 = S m&amp;#039; *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
  - (* IHn&amp;#039; : forall m : nat, double n&amp;#039; = double m -&amp;gt; n&amp;#039; = m&lt;br /&gt;
       forall m : nat, double (S n&amp;#039;) = double m -&amp;gt; S n&amp;#039; = m *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    (* forall m : nat, S (S (double n&amp;#039;)) = double m -&amp;gt; S n&amp;#039; = m *)&lt;br /&gt;
    intros m eq.&lt;br /&gt;
    destruct m as [| m&amp;#039;].&lt;br /&gt;
    + (* S n&amp;#039; = O *)&lt;br /&gt;
      simpl.&lt;br /&gt;
      inversion eq.&lt;br /&gt;
    + (* S n&amp;#039; = S m&amp;#039; *)&lt;br /&gt;
      apply f_equal.&lt;br /&gt;
      (* n&amp;#039; = m&amp;#039; *)&lt;br /&gt;
      apply IHn&amp;#039;.&lt;br /&gt;
      (* double n&amp;#039; = double m&amp;#039; *)&lt;br /&gt;
      inversion eq.&lt;br /&gt;
      (* double n&amp;#039; = double n&amp;#039; *)&lt;br /&gt;
      reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Comentario sobre la estrategia de generalización.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que&lt;br /&gt;
      forall n m,&lt;br /&gt;
        beq_nat n m = true -&amp;gt; n = m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_nat_true : forall n m,&lt;br /&gt;
    beq_nat n m = true -&amp;gt; n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de problema por usar intros antes que induction.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Theorem double_injective_take2_FAILED : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  induction m as [| m&amp;#039;].&lt;br /&gt;
  - (* m = O *) simpl. intros eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) reflexivity.&lt;br /&gt;
    + (* n = S n&amp;#039; *) inversion eq.&lt;br /&gt;
  - (* m = S m&amp;#039; *) intros eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) inversion eq.&lt;br /&gt;
    + (* n = S n&amp;#039; *) apply f_equal.&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo con la táctica &amp;quot;generalize dependent&amp;quot;&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem double_injective_take2 : forall n m,&lt;br /&gt;
    double n = double m -&amp;gt;&lt;br /&gt;
    n = m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  generalize dependent n.&lt;br /&gt;
  induction m as [| m&amp;#039;].&lt;br /&gt;
  - (* m = O *) simpl. intros n eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) reflexivity.&lt;br /&gt;
    + (* n = S n&amp;#039; *) inversion eq.&lt;br /&gt;
  - (* m = S m&amp;#039; *) intros n eq. destruct n as [| n&amp;#039;].&lt;br /&gt;
    + (* n = O *) inversion eq.&lt;br /&gt;
    + (* n = S n&amp;#039; *) apply f_equal. apply IHm&amp;#039;. inversion eq. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Lema para iso posterior.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_id_true : forall x y,&lt;br /&gt;
  beq_id x y = true -&amp;gt; x = y.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [m] [n]. simpl. intros H.&lt;br /&gt;
  assert (H&amp;#039; : m = n). { apply beq_nat_true. apply H. }&lt;br /&gt;
  rewrite H&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Demostra, por inducción sobre l,&lt;br /&gt;
      forall (n : nat) (X : Type) (l : list X),&lt;br /&gt;
        length l = n -&amp;gt;&lt;br /&gt;
        nth_error l n = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem nth_error_after_last:&lt;br /&gt;
  forall (n : nat) (X : Type) (l : list X),&lt;br /&gt;
    length l = n -&amp;gt;&lt;br /&gt;
    nth_error l n = None.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Expnasión de definiciones &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de expansión de una definición con unfold.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition square n := n * n.&lt;br /&gt;
&lt;br /&gt;
Lemma square_mult : forall n m, square (n * m) = square n * square m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  simpl. (* no hace nada *)&lt;br /&gt;
  unfold square.&lt;br /&gt;
  rewrite mult_assoc.&lt;br /&gt;
  assert (H : n * m * n = n * n * m).&lt;br /&gt;
  { rewrite mult_comm.&lt;br /&gt;
    apply mult_assoc. }&lt;br /&gt;
  rewrite H. rewrite mult_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de expansión automática de definiciones.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition foo (x: nat) := 5.&lt;br /&gt;
&lt;br /&gt;
Fact silly_fact_1 : forall m, foo m + 1 = foo (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  simpl.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de no expansión automática de definiciones.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition bar x :=&lt;br /&gt;
  match x with&lt;br /&gt;
  | O   =&amp;gt; 5&lt;br /&gt;
  | S _ =&amp;gt; 5&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Fact silly_fact_2_FAILED : forall m, bar m + 1 = bar (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  simpl. (* No hace nada *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Demostración con destruct *)&lt;br /&gt;
Fact silly_fact_2 : forall m, bar m + 1 = bar (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  destruct m.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Demostración con unfold *)&lt;br /&gt;
Fact silly_fact_2&amp;#039; : forall m, bar m + 1 = bar (m + 1) + 1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros m.&lt;br /&gt;
  unfold bar.&lt;br /&gt;
  destruct m.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Uso de destruct sobre expresiones compuestas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplos de uso de destruct sobre expresiones compuestas.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sillyfun (n : nat) : bool :=&lt;br /&gt;
  if      beq_nat n 3 then false&lt;br /&gt;
  else if beq_nat n 5 then false&lt;br /&gt;
  else                     false.&lt;br /&gt;
&lt;br /&gt;
Theorem sillyfun_false : forall (n : nat),&lt;br /&gt;
    sillyfun n = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. unfold sillyfun.&lt;br /&gt;
  destruct (beq_nat n 3).&lt;br /&gt;
    - (* beq_nat n 3 = true *) reflexivity.&lt;br /&gt;
    - (* beq_nat n 3 = false *) destruct (beq_nat n 5).&lt;br /&gt;
      + (* beq_nat n 5 = true *) reflexivity.&lt;br /&gt;
      + (* beq_nat n 5 = false *) reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Se define la función split por&lt;br /&gt;
      Fixpoint split {X Y : Type} (l : list (X*Y))&lt;br /&gt;
                     : (list X) * (list Y) :=&lt;br /&gt;
        match l with&lt;br /&gt;
        | [] =&amp;gt; ([], [])&lt;br /&gt;
        | (x, y) :: t =&amp;gt;&lt;br /&gt;
            match split t with&lt;br /&gt;
            | (lx, ly) =&amp;gt; (x :: lx, y :: ly)&lt;br /&gt;
            end&lt;br /&gt;
        end.&lt;br /&gt;
&lt;br /&gt;
   Demostrar que split y combine son inversas; es decir,&lt;br /&gt;
        forall X Y (l : list (X * Y)) l1 l2,&lt;br /&gt;
          split l = (l1, l2) -&amp;gt;&lt;br /&gt;
          combine l1 l2 = l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint split {X Y : Type} (l : list (X*Y))&lt;br /&gt;
               : (list X) * (list Y) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | [] =&amp;gt; ([], [])&lt;br /&gt;
  | (x, y) :: t =&amp;gt;&lt;br /&gt;
      match split t with&lt;br /&gt;
      | (lx, ly) =&amp;gt; (x :: lx, y :: ly)&lt;br /&gt;
      end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Theorem combine_split :&lt;br /&gt;
  forall X Y (l : list (X * Y)) l1 l2,&lt;br /&gt;
    split l = (l1, l2) -&amp;gt;&lt;br /&gt;
    combine l1 l2 = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo de precauciones al usar destruct para no perder información.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sillyfun1 (n : nat) : bool :=&lt;br /&gt;
  if      beq_nat n 3 then true&lt;br /&gt;
  else if beq_nat n 5 then true&lt;br /&gt;
  else                     false.&lt;br /&gt;
&lt;br /&gt;
Theorem sillyfun1_odd_FAILED : forall (n : nat),&lt;br /&gt;
    sillyfun1 n = true -&amp;gt;&lt;br /&gt;
    oddb n = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n eq. unfold sillyfun1 in eq.&lt;br /&gt;
  destruct (beq_nat n 3).&lt;br /&gt;
  (* Falso por falta de información *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Solución usando destruct con eqn *)&lt;br /&gt;
Theorem sillyfun1_odd : forall (n : nat),&lt;br /&gt;
    sillyfun1 n = true -&amp;gt;&lt;br /&gt;
    oddb n = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n eq. unfold sillyfun1 in eq.&lt;br /&gt;
  destruct (beq_nat n 3) eqn:Heqe3.&lt;br /&gt;
    - (* e3 = true *) apply beq_nat_true in Heqe3.&lt;br /&gt;
      rewrite -&amp;gt; Heqe3. reflexivity.&lt;br /&gt;
    - (* e3 = false *)&lt;br /&gt;
      destruct (beq_nat n 5) eqn:Heqe5.&lt;br /&gt;
        + (* e5 = true *)&lt;br /&gt;
          apply beq_nat_true in Heqe5.&lt;br /&gt;
          rewrite -&amp;gt; Heqe5. reflexivity.&lt;br /&gt;
        + (* e5 = false *) inversion eq.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
      forall (f : bool -&amp;gt; bool) (b : bool),&lt;br /&gt;
        f (f (f b)) = f b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bool_fn_applied_thrice :&lt;br /&gt;
  forall (f : bool -&amp;gt; bool) (b : bool),&lt;br /&gt;
    f (f (f b)) = f b.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Resumen de tácticas básicas &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Tácticas básicas:&lt;br /&gt;
   - [intros]: move hypotheses/variables from goal to context&lt;br /&gt;
&lt;br /&gt;
   - [reflexivity]: finish the proof (when the goal looks like [e = e])&lt;br /&gt;
&lt;br /&gt;
   - [apply]: prove goal using a hypothesis, lemma, or constructor&lt;br /&gt;
&lt;br /&gt;
   - [apply... in H]: apply a hypothesis, lemma, or constructor to&lt;br /&gt;
     a hypothesis in the context (forward reasoning)&lt;br /&gt;
&lt;br /&gt;
   - [apply... with...]: explicitly specify values for variables&lt;br /&gt;
     that cannot be determined by pattern matching&lt;br /&gt;
&lt;br /&gt;
   - [simpl]: simplify computations in the goal&lt;br /&gt;
&lt;br /&gt;
   - [simpl in H]: ... or a hypothesis&lt;br /&gt;
&lt;br /&gt;
   - [rewrite]: use an equality hypothesis (or lemma) to rewrite&lt;br /&gt;
     the goal&lt;br /&gt;
&lt;br /&gt;
   - [rewrite ... in H]: ... or a hypothesis&lt;br /&gt;
&lt;br /&gt;
   - [symmetry]: changes a goal of the form [t=u] into [u=t]&lt;br /&gt;
&lt;br /&gt;
   - [symmetry in H]: changes a hypothesis of the form [t=u] into [u=t]&lt;br /&gt;
&lt;br /&gt;
   - [unfold]: replace a defined constant by its right-hand side in&lt;br /&gt;
     the goal&lt;br /&gt;
&lt;br /&gt;
   - [unfold... in H]: ... or a hypothesis&lt;br /&gt;
&lt;br /&gt;
   - [destruct... as...]: case analysis on values of inductively&lt;br /&gt;
     defined types&lt;br /&gt;
&lt;br /&gt;
   - [destruct... eqn:...]: specify the name of an equation to be&lt;br /&gt;
     added to the context, recording the result of the case analysis&lt;br /&gt;
&lt;br /&gt;
   - [induction... as...]: induction on values of inductively&lt;br /&gt;
     defined types&lt;br /&gt;
&lt;br /&gt;
   - [inversion]: reason by injectivity and distinctness of constructors&lt;br /&gt;
&lt;br /&gt;
   - [assert (H: e)] (or [assert (e) as H]): introduce a &amp;quot;local&lt;br /&gt;
     lemma&amp;quot; [e] and call it [H]&lt;br /&gt;
&lt;br /&gt;
   - [generalize dependent x]: move the variable [x] (and anything&lt;br /&gt;
     else that depends on it) from the context back to an explicit&lt;br /&gt;
     hypothesis in the goal formula *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. Demostrar que&lt;br /&gt;
      forall (n m : nat),&lt;br /&gt;
        beq_nat n m = beq_nat m n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_nat_sym :&lt;br /&gt;
  forall (n m : nat),&lt;br /&gt;
    beq_nat n m = beq_nat m n.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 12. Demostrar que&lt;br /&gt;
        forall n m p,&lt;br /&gt;
          beq_nat n m = true -&amp;gt;&lt;br /&gt;
          beq_nat m p = true -&amp;gt;&lt;br /&gt;
          beq_nat n p = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_nat_trans :&lt;br /&gt;
  forall n m p,&lt;br /&gt;
    beq_nat n m = true -&amp;gt;&lt;br /&gt;
    beq_nat m p = true -&amp;gt;&lt;br /&gt;
    beq_nat n p = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 13. We proved, in an exercise above, that for all lists of&lt;br /&gt;
   pairs, [combine] is the inverse of [split].  How would you formalize&lt;br /&gt;
   the statement that [split] is the inverse of [combine]?  When is this &lt;br /&gt;
   property true?&lt;br /&gt;
&lt;br /&gt;
   Complete the definition of [split_combine_statement] below with a&lt;br /&gt;
   property that states that [split] is the inverse of&lt;br /&gt;
   [combine]. Then, prove that the property holds. (Be sure to leave&lt;br /&gt;
   your induction hypothesis general by not doing [intros] on more&lt;br /&gt;
   things than necessary.  Hint: what property do you need of [l1]&lt;br /&gt;
   and [l2] for [split] [combine l1 l2 = (l1,l2)] to be true?) &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition split_combine_statement : Prop&lt;br /&gt;
  (* (&amp;quot;[: Prop]&amp;quot; means that we are giving a name to a&lt;br /&gt;
     logical proposition here.) *)&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Theorem split_combine : split_combine_statement.&lt;br /&gt;
Proof.&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 14. Demostrar que&lt;br /&gt;
      forall (X : Type) (test : X -&amp;gt; bool) (x : X) (l lf : list X),&lt;br /&gt;
        filter test l = x :: lf -&amp;gt;&lt;br /&gt;
        test x = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem filter_exercise :&lt;br /&gt;
  forall (X : Type) (test : X -&amp;gt; bool) (x : X) (l lf : list X),&lt;br /&gt;
    filter test l = x :: lf -&amp;gt;&lt;br /&gt;
    test x = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 15. Definir, por recursión, las funciones forallb y existsb&lt;br /&gt;
   tales que &lt;br /&gt;
   + (forallb p xs) se verifica si todos los elementos de xs cumplen&lt;br /&gt;
     p. Por ejemplo, &lt;br /&gt;
        forallb oddb [1;3;5;7;9]   = true&lt;br /&gt;
        forallb negb [false;false] = true&lt;br /&gt;
        forallb evenb [0;2;4;5]    = false&lt;br /&gt;
        forallb (beq_nat 5) []     = true&lt;br /&gt;
   + (existsb p xs) se verifica si algún elemento de xs cumple p. Por&lt;br /&gt;
     ejemplo, &lt;br /&gt;
        existsb (beq_nat 5) [0;2;3;6]         = false&lt;br /&gt;
        existsb (andb true) [true;true;false] = true&lt;br /&gt;
        existsb oddb [1;0;0;0;0;3]            = true&lt;br /&gt;
        existsb evenb []                      = false&lt;br /&gt;
&lt;br /&gt;
   Redefinir, usando forallb y negb, la función existsb&amp;#039; y demostrar su&lt;br /&gt;
   equivalencia con existsb.&lt;br /&gt;
   ------------------------------------------------------------------ *)&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/SLC2018/index.php?title=Temas&amp;diff=109</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=109"/>
		<updated>2018-05-06T08:59:32Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
** Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
** Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T3_Listas.v]]).&lt;br /&gt;
** Tema 4: [[Tema 4 | Polimorfismo y orden superior en Coq]].&lt;br /&gt;
** Tema 5: [[Tema 5 | Tácticas básicas]].&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
** Miriam Medrán Navarro (Tema 4).&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_4&amp;diff=108</id>
		<title>Tema 4</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_4&amp;diff=108"/>
		<updated>2018-05-03T12:37:25Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T4: Polimorfismo y funciones deo orden superior en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T3_Listas.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Polimorfismo&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Listas polimórficas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo boollist para representar las listas de&lt;br /&gt;
   booleanos con los constructores bool_nil y bool_cons tales que &lt;br /&gt;
   + bool_nil es la lista vacía y&lt;br /&gt;
   + (bool_cons x ys) es la lista obtenida añadiendo el booleano x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive boollist : Type :=&lt;br /&gt;
  | bool_nil : boollist&lt;br /&gt;
  | bool_cons : bool -&amp;gt; boollist -&amp;gt; boollist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (list X) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil es la lista vacía y&lt;br /&gt;
   + (cons x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list (X:Type) : Type :=&lt;br /&gt;
  | nil  : list X&lt;br /&gt;
  | cons : X -&amp;gt; list X -&amp;gt; list X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de list.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check list.&lt;br /&gt;
(* ===&amp;gt; list : Type -&amp;gt; Type *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (nil nat).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (nil nat).&lt;br /&gt;
(* ===&amp;gt; nil nat : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 3 (nil nat)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 3 (nil nat)).&lt;br /&gt;
(* ===&amp;gt; cons nat 3 (nil nat) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check nil.&lt;br /&gt;
(* ===&amp;gt; nil : forall X : Type, list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de cons.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check cons.&lt;br /&gt;
(* ===&amp;gt; cons : forall X : Type, X -&amp;gt; list X -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
(* ==&amp;gt; cons nat 2 (cons nat 1 (nil nat)) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat (X : Type) (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (X : Type) (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0 =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat1 :&lt;br /&gt;
  repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat2 :&lt;br /&gt;
  repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Se definen los siguientes tipos&lt;br /&gt;
      Inductive mumble : Type :=&lt;br /&gt;
        | a : mumble&lt;br /&gt;
        | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
        | c : mumble.&lt;br /&gt;
      &lt;br /&gt;
      Inductive grumble (X:Type) : Type :=&lt;br /&gt;
        | d : mumble -&amp;gt; grumble X&lt;br /&gt;
        | e : X -&amp;gt; grumble X.&lt;br /&gt;
  &lt;br /&gt;
   Decidir cuáles de los siguientes expresiones son del tipo (grumble X)&lt;br /&gt;
   para algún X:&lt;br /&gt;
      - [d (b a 5)]&lt;br /&gt;
      - [d mumble (b a 5)]&lt;br /&gt;
      - [d bool (b a 5)]&lt;br /&gt;
      - [e bool true]&lt;br /&gt;
      - [e mumble (b c 0)]&lt;br /&gt;
      - [e bool (b c 0)]&lt;br /&gt;
      - [c]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
Inductive mumble : Type :=&lt;br /&gt;
  | a : mumble&lt;br /&gt;
  | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
  | c : mumble.&lt;br /&gt;
&lt;br /&gt;
Inductive grumble (X:Type) : Type :=&lt;br /&gt;
  | d : mumble -&amp;gt; grumble X&lt;br /&gt;
  | e : X -&amp;gt; grumble X.&lt;br /&gt;
&lt;br /&gt;
End MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inferencia de tipos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat&amp;#039; X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular los tipos de repeat&amp;#039; y repeat.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check repeat&amp;#039;.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
Check repeat.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Síntesis de los tipos de los argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil _&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons _ x (repeat&amp;#039;&amp;#039; _ x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123 :=&lt;br /&gt;
  cons nat 1 (cons nat 2 (cons nat 3 (nil nat))).&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039; :=&lt;br /&gt;
  cons _ 1 (cons _ 2 (cons _ 3 (nil _))).&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Argumentos implícitos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Especificar las siguientes funciones y sus argumentos&lt;br /&gt;
   explícitos e implícitos:&lt;br /&gt;
   + nil&lt;br /&gt;
   + constructor&lt;br /&gt;
   + repeat&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Arguments nil {X}.&lt;br /&gt;
Arguments cons {X} _ _.&lt;br /&gt;
Arguments repeat {X} x count.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039; := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons x (repeat&amp;#039;&amp;#039;&amp;#039; x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;1 :&lt;br /&gt;
  repeat&amp;#039;&amp;#039;&amp;#039; 4 2 = cons 4 (cons 4 nil).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;2 :&lt;br /&gt;
  repeat false 1 = cons false nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (list&amp;#039; {X}) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil&amp;#039; es la lista vacía y&lt;br /&gt;
   + (cons&amp;#039; x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list&amp;#039; {X:Type} : Type :=&lt;br /&gt;
  | nil&amp;#039;  : list&amp;#039;&lt;br /&gt;
  | cons&amp;#039; : X -&amp;gt; list&amp;#039; -&amp;gt; list&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      app {X : Type} (l1 l2 : list X) : (list X)&lt;br /&gt;
   tal que (app xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint app {X : Type} (l1 l2 : list X) : (list X) :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil      =&amp;gt; l2&lt;br /&gt;
  | cons h t =&amp;gt; cons h (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev {X:Type} (l:list X) : list X&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
      rev (cons true nil) = cons true nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev {X:Type} (l:list X) : list X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil      =&amp;gt; nil&lt;br /&gt;
  | cons h t =&amp;gt; app (rev t) (cons h nil)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1 :&lt;br /&gt;
  rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_rev2:&lt;br /&gt;
  rev (cons true nil) = cons true nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length {X : Type} (l : list X) : nat &lt;br /&gt;
   tal que (length xs) es el número de elementos de xs. Por ejemplo,&lt;br /&gt;
      length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil       =&amp;gt; 0&lt;br /&gt;
  | cons _ l&amp;#039; =&amp;gt; S (length l&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_length1:&lt;br /&gt;
  length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Explicitación de argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Especificar que la siguiente definición es errónea&lt;br /&gt;
      Fail Definition mynil := nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fail Definition mynil := nil.&lt;br /&gt;
(* ==&amp;gt; Error: Cannot infer the implicit parameter X of nil. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Completar la definición anterior para obtener la lista&lt;br /&gt;
   vacía de números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mynil : list nat := nil.&lt;br /&gt;
&lt;br /&gt;
(* Alternativamente *)&lt;br /&gt;
Definition mynil&amp;#039; := @nil nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir las siguientes abreviaturas&lt;br /&gt;
   + &amp;quot;x :: y&amp;quot;         para (cons x y)&lt;br /&gt;
   + &amp;quot;[ ]&amp;quot;            para nil&lt;br /&gt;
   + &amp;quot;[ x ; .. ; y ]&amp;quot; para (cons x .. (cons y []) ..).&lt;br /&gt;
   + &amp;quot;x ++ y&amp;quot;         para (app x y)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: y&amp;quot; := (cons x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y []) ..).&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039;&amp;#039; := [1; 2; 3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Ejercicios  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall (X:Type), forall l:list X,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que la concatenación es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall A (l m n:list A),&lt;br /&gt;
  l ++ m ++ n = (l ++ m) ++ n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros A l m n.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que la longitud de una concatenación es la suma de&lt;br /&gt;
   las longitudes de las listas (es decir, es un homomorfismo).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma app_length : forall (X:Type) (l1 l2 : list X),&lt;br /&gt;
  length (l1 ++ l2) = length l1 + length l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X l1 l2.&lt;br /&gt;
  induction l1.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl1. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_app_distr: forall X (l1 l2 : list X),&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X l1 l2.&lt;br /&gt;
  induction l1.&lt;br /&gt;
  + simpl. rewrite app_nil_r. reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl1, app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      rev (rev l) = l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall X : Type, forall l : list X,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite rev_app_distr, IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Polimorfismo de pares  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo prod (X Y) con el constructor pair tal que &lt;br /&gt;
   (pair x y) es el par cuyas componentes son x e y.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive prod (X Y : Type) : Type :=&lt;br /&gt;
| pair : X -&amp;gt; Y -&amp;gt; prod X Y.&lt;br /&gt;
&lt;br /&gt;
Arguments pair {X} {Y} _ _.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;( x , y )&amp;quot; para (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;X * Y&amp;quot; para (prod X Y) &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;X * Y&amp;quot; := (prod X Y) : type_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst {X Y : Type} (p : X * Y) : X&lt;br /&gt;
   tal que (fst p) es la primera componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst {X Y : Type} (p : X * Y) : X :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd {X Y : Type} (p : X * Y) &lt;br /&gt;
   tal que (snd p) es la segunda componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd {X Y : Type} (p : X * Y) : Y :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) &lt;br /&gt;
   tal que (combine lx ly) es la lista obtenida emparejando los&lt;br /&gt;
   elementos de lx y ly (como zip de Haskell).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) :=&lt;br /&gt;
  match lx, ly with&lt;br /&gt;
  | []     , _       =&amp;gt; []&lt;br /&gt;
  | _      , []      =&amp;gt; []&lt;br /&gt;
  | x :: tx, y :: ty =&amp;gt; (x, y) :: (combine tx ty)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Check combine&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check @combine.&lt;br /&gt;
(* ==&amp;gt; forall X Y : Type, list X -&amp;gt; list Y -&amp;gt; list (X * Y)*)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
(* ==&amp;gt; [(1, false); (2, false)] : list (nat * bool) *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y)&lt;br /&gt;
   tal que (split l) es el par de lista (lx,ly) cuyo emparejamiento es&lt;br /&gt;
   l. (La función split es como unzip de Haskell). Por ejemplo,&lt;br /&gt;
      split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y) :=&lt;br /&gt;
 match l with&lt;br /&gt;
 | []          =&amp;gt; ([], [])&lt;br /&gt;
 | (x, y) :: t =&amp;gt; let s := split t in (x :: fst s, y :: snd s)&lt;br /&gt;
end.&lt;br /&gt;
&lt;br /&gt;
Example test_split:&lt;br /&gt;
  split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Resultados opcionales polimórficos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (option X) con los constructores Some y None&lt;br /&gt;
   tales que &lt;br /&gt;
   + (Some x) es un valor de tipo X.&lt;br /&gt;
   + None es el valor nulo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive option (X:Type) : Type :=&lt;br /&gt;
  | Some : X -&amp;gt; option X&lt;br /&gt;
  | None : option X.&lt;br /&gt;
&lt;br /&gt;
Arguments Some {X} _.&lt;br /&gt;
Arguments None {X}.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
   tal que (nth_error l n) es el n-ésimo elemento de l. Por ejemplo, &lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
      nth_error [true] 2    = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []      =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O then Some a else nth_error l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [true] 2 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      hd_error {X : Type} (l : list X) : option X&lt;br /&gt;
   tal que (hd_error l) es el primer elemento de l. Por ejemplo,&lt;br /&gt;
      hd_error [1;2]     = Some 1.&lt;br /&gt;
      hd_error [[1];[2]] = Some [1].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error {X : Type} (l : list X) : option X :=&lt;br /&gt;
 match l with &lt;br /&gt;
    | []     =&amp;gt; None&lt;br /&gt;
    | x :: _ =&amp;gt; Some x&lt;br /&gt;
 end.&lt;br /&gt;
&lt;br /&gt;
Check @hd_error.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [1;2] = Some 1.&lt;br /&gt;
 Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error2 : hd_error  [[1];[2]]  = Some [1].&lt;br /&gt;
 Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones como datos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones de orden superior &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X &lt;br /&gt;
   tal que (doit3times f) aplica 3 veces la función f. Por ejemplo,&lt;br /&gt;
      doit3times minustwo 9 = 3.&lt;br /&gt;
      doit3times negb true  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X :=&lt;br /&gt;
  f (f (f n)).&lt;br /&gt;
&lt;br /&gt;
Check @doit3times.&lt;br /&gt;
(* ===&amp;gt; doit3times : forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X *)&lt;br /&gt;
&lt;br /&gt;
Example test_doit3times: doit3times minustwo 9 = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_doit3times&amp;#039;: doit3times negb true = false.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Filtrado  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      filter {X:Type} (test: X-&amp;gt;bool) (l:list X) : (list X)&lt;br /&gt;
   tal que (filter p l) es la lista de los elementos de l que verifican&lt;br /&gt;
   p. Por ejemplo,&lt;br /&gt;
      filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fixpoint filter {X:Type} (test: X-&amp;gt;bool) (l:list X)&lt;br /&gt;
                : (list X) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; if test h then h :: (filter test t)&lt;br /&gt;
                       else       filter test t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_filter1: filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Definition length_is_1 {X : Type} (l : list X) : bool :=&lt;br /&gt;
  beq_nat (length l) 1.&lt;br /&gt;
&lt;br /&gt;
Example test_filter2:&lt;br /&gt;
    filter length_is_1&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      countoddmembers&amp;#039; (l:list nat) : nat &lt;br /&gt;
   tal que countoddmembers&amp;#039; l) es el número de elementos impares de&lt;br /&gt;
   l. Por ejemplo,&lt;br /&gt;
      countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers&amp;#039; [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers&amp;#039; nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers&amp;#039; (l:list nat) : nat :=&lt;br /&gt;
  length (filter oddb l).&lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers&amp;#039;1:   countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;2:   countoddmembers&amp;#039; [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;3:   countoddmembers&amp;#039; nil = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones anónimas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_anon_fun&amp;#039;:&lt;br /&gt;
  doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular&lt;br /&gt;
      filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
             [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_filter2&amp;#039;:&lt;br /&gt;
    filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      filter_even_gt7 (l : list nat) : list nat&lt;br /&gt;
   tal que (filter_even_gt7 l) es la lista de los elemntos de l que son&lt;br /&gt;
   pares y mayores que 7. Por ejemplo,&lt;br /&gt;
      filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
      filter_even_gt7 [5;2;6;19;129]      = [].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition filter_even_gt7 (l : list nat) : list nat :=&lt;br /&gt;
  filter (fun x =&amp;gt; evenb x &amp;amp;&amp;amp; leb 7 x) l.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_1 :&lt;br /&gt;
  filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
 Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_2 :&lt;br /&gt;
  filter_even_gt7 [5;2;6;19;129] = [].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      partition : forall X : Type,&lt;br /&gt;
                  (X -&amp;gt; bool) -&amp;gt; list X -&amp;gt; list X * list X&lt;br /&gt;
   tal que (patition p l) es el par de lista (lx,ly) tal que lx es la&lt;br /&gt;
   lista de los elementos de l que cumplen p y ly la de las que no lo&lt;br /&gt;
   cumplen. Por ejemplo,&lt;br /&gt;
      partition oddb [1;2;3;4;5]         = ([1;3;5], [2;4]).&lt;br /&gt;
      partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition partition {X : Type}&lt;br /&gt;
                     (test : X -&amp;gt; bool)&lt;br /&gt;
                     (l : list X)&lt;br /&gt;
                   : list X * list X :=&lt;br /&gt;
  (filter test l, filter (fun x =&amp;gt; negb (test x)) l).&lt;br /&gt;
&lt;br /&gt;
Example test_partition1: partition oddb [1;2;3;4;5] = ([1;3;5], [2;4]).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_partition2: partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Aplicación a todos los elementos (map)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) &lt;br /&gt;
   tal que (map f l) es la lista obtenida aplicando f a todos los&lt;br /&gt;
   elementos de l. Por ejemplo,&lt;br /&gt;
      map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
      map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
      map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
        = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; (f h) :: (map f t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_map1: map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map2:&lt;br /&gt;
  map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map3:&lt;br /&gt;
    map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
  = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      map f (rev l) = rev (map f l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma map_app_distr : forall (X Y : Type) (f : X -&amp;gt; Y) (l t : list X),&lt;br /&gt;
    map f (l ++ t) = map f l ++ map f t.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X Y f l t.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem map_rev : forall (X Y : Type) (f : X -&amp;gt; Y) (l : list X),&lt;br /&gt;
  map f (rev l) = rev (map f l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X Y f l.&lt;br /&gt;
  induction l.&lt;br /&gt;
  + reflexivity.&lt;br /&gt;
  + simpl. rewrite map_app_distr, IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X) : (list Y)&lt;br /&gt;
   tal que (flat_map f l) es la concatenación de las listas obtenidas&lt;br /&gt;
   aplicando f a l. Por ejemplo,&lt;br /&gt;
      flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4] = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X) &lt;br /&gt;
                   : (list Y) :=&lt;br /&gt;
   match l with&lt;br /&gt;
  | [] =&amp;gt; []&lt;br /&gt;
  | x :: t =&amp;gt; f x ++ flat_map f t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_flat_map1:&lt;br /&gt;
  flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4]&lt;br /&gt;
  = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X) : option Y&lt;br /&gt;
   tal que (option_map f xo) es la aplicación de f a xo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X)&lt;br /&gt;
                      : option Y :=&lt;br /&gt;
  match xo with&lt;br /&gt;
    | None   =&amp;gt; None&lt;br /&gt;
    | Some x =&amp;gt; Some (f x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Plegados (fold)  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y) : Y&lt;br /&gt;
   tal que (fold f l b) es el plegado de l con la operación f a partir&lt;br /&gt;
   del elemento b. Por ejemplo,&lt;br /&gt;
      fold mult [1;2;3;4] 1                 = 24.&lt;br /&gt;
      fold andb [true;true;false;true] true = false.&lt;br /&gt;
      fold app  [[1];[];[2;3];[4]] []       = [1;2;3;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y)&lt;br /&gt;
                         : Y :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; b&lt;br /&gt;
  | h :: t =&amp;gt; f h (fold f t b)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Check (fold andb).&lt;br /&gt;
(* ===&amp;gt; fold andb : list bool -&amp;gt; bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
Example fold_example1 :&lt;br /&gt;
  fold mult [1;2;3;4] 1 = 24.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example2 :&lt;br /&gt;
  fold andb [true;true;false;true] true = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example3 :&lt;br /&gt;
  fold app  [[1];[];[2;3];[4]] [] = [1;2;3;4].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones que construyen funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      constfun {X: Type} (x: X) : nat-&amp;gt;X&lt;br /&gt;
   tal que (constfun x) es la función que a todos los naturales le&lt;br /&gt;
   asigna el x. Por ejemplo, si se define &lt;br /&gt;
      Definition ftrue := constfun true.&lt;br /&gt;
   entonces,&lt;br /&gt;
      ftrue 0         = true.&lt;br /&gt;
      (constfun 5) 99 = 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition constfun {X: Type} (x: X) : nat-&amp;gt;X :=&lt;br /&gt;
  fun (k:nat) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
Definition ftrue := constfun true.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example1 : ftrue 0 = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example2 : (constfun 5) 99 = 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de plus.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check plus.&lt;br /&gt;
(* ==&amp;gt; nat -&amp;gt; nat -&amp;gt; nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus3 : nat -&amp;gt; nat&lt;br /&gt;
   tal que (plus3 x) es tres más x. Por ejemplo,&lt;br /&gt;
      plus3 4               = 7.&lt;br /&gt;
      doit3times plus3 0    = 9.&lt;br /&gt;
      doit3times (plus 3) 0 = 9.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus3 := plus 3.&lt;br /&gt;
&lt;br /&gt;
Example test_plus3 :    plus3 4 = 7.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039; :   doit3times plus3 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039;&amp;#039; :  doit3times (plus 3) 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
Module Exercises.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_length {X : Type} (l : list X) : nat&lt;br /&gt;
   tal que (fold_length l) es la longitud de l. Por ejemplo,&lt;br /&gt;
      fold_length [4;7;0] = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition fold_length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  fold (fun _ n =&amp;gt; S n) l 0.&lt;br /&gt;
&lt;br /&gt;
Example test_fold_length1 : fold_length [4;7;0] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      fold_length l = length l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fold_length_correct : forall X (l : list X),&lt;br /&gt;
  fold_length l = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X l.&lt;br /&gt;
  unfold fold_length.&lt;br /&gt;
  induction l.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y&lt;br /&gt;
   tal que (fold_map f l) es la lista obtenida aplicando f a los&lt;br /&gt;
   elementos de l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y :=&lt;br /&gt;
   fold (fun x t =&amp;gt; (f x) :: t)  l [].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que fold_map es equivalente a map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fold_map_correct : forall (X Y : Type) (f : X -&amp;gt; Y) (l : list X),&lt;br /&gt;
     fold_map f l = map f l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros X Y f l.&lt;br /&gt;
  unfold fold_map.&lt;br /&gt;
  induction l.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      prod_curry {X Y Z : Type} (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z&lt;br /&gt;
   tal que (prod_curry f x y) es la versión curryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_curry {X Y Z : Type}&lt;br /&gt;
  (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z := f (x, y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      prod_uncurry {X Y Z : Type} (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z&lt;br /&gt;
   tal que (prod_uncurry f p) es la versión incurryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_uncurry {X Y Z : Type}&lt;br /&gt;
  (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z := f (fst p) (snd p).&lt;br /&gt;
&lt;br /&gt;
Check @prod_curry.&lt;br /&gt;
Check @prod_uncurry.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      prod_curry (prod_uncurry f) x y = f x y&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem uncurry_curry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : X -&amp;gt; Y -&amp;gt; Z)&lt;br /&gt;
                        x y,&lt;br /&gt;
  prod_curry (prod_uncurry f) x y = f x y.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem curry_uncurry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : (X * Y) -&amp;gt; Z) (p : X * Y),&lt;br /&gt;
  prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros.&lt;br /&gt;
  destruct p.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Demostrar que&lt;br /&gt;
      forall X n l, length l = n -&amp;gt; @nth_error X l n = None&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. En los siguientes ejercicios se trabajará con la&lt;br /&gt;
   definición de Church de los números naturales: el número natural n es&lt;br /&gt;
   la función que toma como argumento una función f y devuelve como&lt;br /&gt;
   valor la aplicación de n veces la función f. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module Church.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo nat para los números naturales de Church. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition nat := forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      one : nat&lt;br /&gt;
   tal que one es el número uno de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition one : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      two : nat&lt;br /&gt;
   tal que two es el número dos de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition two : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f (f x).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      zero : nat&lt;br /&gt;
   tal que zero es el número cero de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition zero : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      three : nat&lt;br /&gt;
   tal que three es el número tres de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition three : nat := @doit3times.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      succ (n : nat) : nat&lt;br /&gt;
   tal que (succ n) es el siguiente del número n de Church. Por ejemplo, &lt;br /&gt;
      succ zero = one.&lt;br /&gt;
      succ one  = two.&lt;br /&gt;
      succ two  = three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition succ (n : nat) : nat :=&lt;br /&gt;
   fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f (n X f x).&lt;br /&gt;
&lt;br /&gt;
Example succ_1 : succ zero = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example succ_2 : succ one = two.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example succ_3 : succ two = three.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      plus (n m : nat) : nat&lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus zero one             = one.&lt;br /&gt;
      plus two three            = plus three two.&lt;br /&gt;
      plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus (n m : nat) : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; m X f (n X f x).&lt;br /&gt;
&lt;br /&gt;
Example plus_1 : plus zero one = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example plus_2 : plus two three = plus three two.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example plus_3 :&lt;br /&gt;
  plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      mult (n m : nat) : nat&lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult one one = one.&lt;br /&gt;
      mult zero (plus three three) = zero.&lt;br /&gt;
      mult two three = plus three three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mult (n m : nat) : nat :=&lt;br /&gt;
   fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; n X (m X f) x.&lt;br /&gt;
&lt;br /&gt;
Example mult_1 : mult one one = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example mult_2 : mult zero (plus three three) = zero.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example mult_3 : mult two three = plus three three.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      exp (n m : nat) : nat&lt;br /&gt;
   tal que (exp n m) es la potencia m-ésima de n. Por ejemplo, &lt;br /&gt;
      exp two two = plus two two.&lt;br /&gt;
      exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
      exp three zero = one.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition exp (n m : nat) : nat :=&lt;br /&gt;
  ( fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; (m (X -&amp;gt; X) (n X) f) x).&lt;br /&gt;
&lt;br /&gt;
Example exp_1 : exp two two = plus two two.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example exp_2 : exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example exp_3 : exp three zero = one.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
End Church.&lt;br /&gt;
&lt;br /&gt;
End Exercises.&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/SLC2018/index.php?title=Tema_4&amp;diff=105</id>
		<title>Tema 4</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_4&amp;diff=105"/>
		<updated>2018-05-02T22:12:31Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T4: Polimorfismo y funciones deo orden superior en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T3_Listas.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Polimorfismo&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Listas polimórficas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo boollist para representar las listas de&lt;br /&gt;
   booleanos con los constructores bool_nil y bool_cons tales que &lt;br /&gt;
   + bool_nil es la lista vacía y&lt;br /&gt;
   + (bool_cons x ys) es la lista obtenida añadiendo el booleano x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive boollist : Type :=&lt;br /&gt;
  | bool_nil : boollist&lt;br /&gt;
  | bool_cons : bool -&amp;gt; boollist -&amp;gt; boollist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo (list X) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil es la lista vacía y&lt;br /&gt;
   + (cons x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list (X:Type) : Type :=&lt;br /&gt;
  | nil  : list X&lt;br /&gt;
  | cons : X -&amp;gt; list X -&amp;gt; list X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de list.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check list.&lt;br /&gt;
(* ===&amp;gt; list : Type -&amp;gt; Type *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (nil nat).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (nil nat).&lt;br /&gt;
(* ===&amp;gt; nil nat : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 3 (nil nat)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 3 (nil nat)).&lt;br /&gt;
(* ===&amp;gt; cons nat 3 (nil nat) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check nil.&lt;br /&gt;
(* ===&amp;gt; nil : forall X : Type, list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de cons.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check cons.&lt;br /&gt;
(* ===&amp;gt; cons : forall X : Type, X -&amp;gt; list X -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
(* ==&amp;gt; cons nat 2 (cons nat 1 (nil nat)) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat (X : Type) (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (X : Type) (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0 =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat1 :&lt;br /&gt;
  repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat2 :&lt;br /&gt;
  repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Se definen los siguientes tipos&lt;br /&gt;
      Inductive mumble : Type :=&lt;br /&gt;
        | a : mumble&lt;br /&gt;
        | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
        | c : mumble.&lt;br /&gt;
      &lt;br /&gt;
      Inductive grumble (X:Type) : Type :=&lt;br /&gt;
        | d : mumble -&amp;gt; grumble X&lt;br /&gt;
        | e : X -&amp;gt; grumble X.&lt;br /&gt;
  &lt;br /&gt;
   Decidir cuáles de los siguientes expresiones son del tipo (grumble X)&lt;br /&gt;
   para algún X:&lt;br /&gt;
      - [d (b a 5)]&lt;br /&gt;
      - [d mumble (b a 5)]&lt;br /&gt;
      - [d bool (b a 5)]&lt;br /&gt;
      - [e bool true]&lt;br /&gt;
      - [e mumble (b c 0)]&lt;br /&gt;
      - [e bool (b c 0)]&lt;br /&gt;
      - [c]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
Inductive mumble : Type :=&lt;br /&gt;
  | a : mumble&lt;br /&gt;
  | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
  | c : mumble.&lt;br /&gt;
&lt;br /&gt;
Inductive grumble (X:Type) : Type :=&lt;br /&gt;
  | d : mumble -&amp;gt; grumble X&lt;br /&gt;
  | e : X -&amp;gt; grumble X.&lt;br /&gt;
&lt;br /&gt;
End MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inferencia de tipos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat&amp;#039; X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular los tipos de repeat&amp;#039; y repeat.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check repeat&amp;#039;.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
Check repeat.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Síntesis de los tipos de los argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil _&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons _ x (repeat&amp;#039;&amp;#039; _ x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123 :=&lt;br /&gt;
  cons nat 1 (cons nat 2 (cons nat 3 (nil nat))).&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039; :=&lt;br /&gt;
  cons _ 1 (cons _ 2 (cons _ 3 (nil _))).&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Argumentos implícitos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Especificar las siguientes funciones y sus argumentos&lt;br /&gt;
   explícitos e implícitos:&lt;br /&gt;
   + nil&lt;br /&gt;
   + constructor&lt;br /&gt;
   + repeat&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Arguments nil {X}.&lt;br /&gt;
Arguments cons {X} _ _.&lt;br /&gt;
Arguments repeat {X} x count.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039; := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons x (repeat&amp;#039;&amp;#039;&amp;#039; x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;1 :&lt;br /&gt;
  repeat&amp;#039;&amp;#039;&amp;#039; 4 2 = cons 4 (cons 4 nil).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;2 :&lt;br /&gt;
  repeat false 1 = cons false nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo (list&amp;#039; {X}) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil&amp;#039; es la lista vacía y&lt;br /&gt;
   + (cons&amp;#039; x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list&amp;#039; {X:Type} : Type :=&lt;br /&gt;
  | nil&amp;#039;  : list&amp;#039;&lt;br /&gt;
  | cons&amp;#039; : X -&amp;gt; list&amp;#039; -&amp;gt; list&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      app {X : Type} (l1 l2 : list X) : (list X)&lt;br /&gt;
   tal que (app xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint app {X : Type} (l1 l2 : list X) : (list X) :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil      =&amp;gt; l2&lt;br /&gt;
  | cons h t =&amp;gt; cons h (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev {X:Type} (l:list X) : list X&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
      rev (cons true nil) = cons true nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev {X:Type} (l:list X) : list X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil      =&amp;gt; nil&lt;br /&gt;
  | cons h t =&amp;gt; app (rev t) (cons h nil)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1 :&lt;br /&gt;
  rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_rev2:&lt;br /&gt;
  rev (cons true nil) = cons true nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length {X : Type} (l : list X) : nat &lt;br /&gt;
   tal que (length xs) es el número de elementos de xs. Por ejemplo,&lt;br /&gt;
      length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil       =&amp;gt; 0&lt;br /&gt;
  | cons _ l&amp;#039; =&amp;gt; S (length l&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_length1:&lt;br /&gt;
  length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Explicitación de argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Especificar que la siguiente definición es errónea&lt;br /&gt;
      Fail Definition mynil := nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fail Definition mynil := nil.&lt;br /&gt;
(* ==&amp;gt; Error: Cannot infer the implicit parameter X of nil. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Completar la definición anterior para obtener la lista&lt;br /&gt;
   vacía de números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mynil : list nat := nil.&lt;br /&gt;
&lt;br /&gt;
(* Alternativamente *)&lt;br /&gt;
Definition mynil&amp;#039; := @nil nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir las siguientes abreviaturas&lt;br /&gt;
   + &amp;quot;x :: y&amp;quot;         para (cons x y)&lt;br /&gt;
   + &amp;quot;[ ]&amp;quot;            para nil&lt;br /&gt;
   + &amp;quot;[ x ; .. ; y ]&amp;quot; para (cons x .. (cons y []) ..).&lt;br /&gt;
   + &amp;quot;x ++ y&amp;quot;         para (app x y)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: y&amp;quot; := (cons x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y []) ..).&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039;&amp;#039; := [1; 2; 3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Ejercicios  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall (X:Type), forall l:list X,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la concatenación es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall A (l m n:list A),&lt;br /&gt;
  l ++ m ++ n = (l ++ m) ++ n.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la longitud de una concatenación es la suma de&lt;br /&gt;
   las longitudes de las listas (es decir, es un homomorfismo).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma app_length : forall (X:Type) (l1 l2 : list X),&lt;br /&gt;
  length (l1 ++ l2) = length l1 + length l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_app_distr: forall X (l1 l2 : list X),&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      rev (rev l) = l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall X : Type, forall l : list X,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Polimorfismo de pares  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo prod (X Y) con el constructor pair tal que &lt;br /&gt;
   (pair x y) es el par cuyas componentes son x e y.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive prod (X Y : Type) : Type :=&lt;br /&gt;
| pair : X -&amp;gt; Y -&amp;gt; prod X Y.&lt;br /&gt;
&lt;br /&gt;
Arguments pair {X} {Y} _ _.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;( x , y )&amp;quot; para (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;X * Y&amp;quot; para (prod X Y) &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;X * Y&amp;quot; := (prod X Y) : type_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst {X Y : Type} (p : X * Y) : X&lt;br /&gt;
   tal que (fst p) es la primera componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst {X Y : Type} (p : X * Y) : X :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd {X Y : Type} (p : X * Y) &lt;br /&gt;
   tal que (snd p) es la segunda componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd {X Y : Type} (p : X * Y) : Y :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) &lt;br /&gt;
   tal que (combine lx ly) es la lista obtenida emparejando los&lt;br /&gt;
   elementos de lx y ly (como zip de Haskell).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) :=&lt;br /&gt;
  match lx, ly with&lt;br /&gt;
  | []     , _       =&amp;gt; []&lt;br /&gt;
  | _      , []      =&amp;gt; []&lt;br /&gt;
  | x :: tx, y :: ty =&amp;gt; (x, y) :: (combine tx ty)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Check combine&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y)&lt;br /&gt;
   tal que (split l) es el par de lista (lx,ly) cuyo emparejamiento es&lt;br /&gt;
   l. (La función split es como unzip de Haskell). Por ejemplo,&lt;br /&gt;
      split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y)&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_split:&lt;br /&gt;
  split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
Proof.&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Resultados opcionales polimórficos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (option X) con los constructores Some y None&lt;br /&gt;
   tales que &lt;br /&gt;
   + (Some x) es un valor de tipo X.&lt;br /&gt;
   + None es el valor nulo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive option (X:Type) : Type :=&lt;br /&gt;
  | Some : X -&amp;gt; option X&lt;br /&gt;
  | None : option X.&lt;br /&gt;
&lt;br /&gt;
Arguments Some {X} _.&lt;br /&gt;
Arguments None {X}.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
   tal que (nth_error l n) es el n-ésimo elemento de l. Por ejemplo, &lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
      nth_error [true] 2    = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []      =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O then Some a else nth_error l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [true] 2 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      hd_error {X : Type} (l : list X) : option X&lt;br /&gt;
   tal que (hd_error l) es el primer elemento de l. Por ejemplo,&lt;br /&gt;
      hd_error [1;2]     = Some 1.&lt;br /&gt;
      hd_error [[1];[2]] = Some [1].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error {X : Type} (l : list X) : option X&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Check @hd_error.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [1;2] = Some 1.&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
Example test_hd_error2 : hd_error  [[1];[2]]  = Some [1].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones como datos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones de orden superior &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X &lt;br /&gt;
   tal que (doit3times f) aplica 3 veces la función f. Por ejemplo,&lt;br /&gt;
      doit3times minustwo 9 = 3.&lt;br /&gt;
      doit3times negb true  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X :=&lt;br /&gt;
  f (f (f n)).&lt;br /&gt;
&lt;br /&gt;
Check @doit3times.&lt;br /&gt;
(* ===&amp;gt; doit3times : forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X *)&lt;br /&gt;
&lt;br /&gt;
Example test_doit3times: doit3times minustwo 9 = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_doit3times&amp;#039;: doit3times negb true = false.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Filtrado  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      filter {X:Type} (test: X-&amp;gt;bool) (l:list X) : (list X)&lt;br /&gt;
   tal que (filter p l) es la lista de los elementos de l que verifican&lt;br /&gt;
   p. Por ejemplo,&lt;br /&gt;
      filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fixpoint filter {X:Type} (test: X-&amp;gt;bool) (l:list X)&lt;br /&gt;
                : (list X) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; if test h then h :: (filter test t)&lt;br /&gt;
                       else       filter test t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_filter1: filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Definition length_is_1 {X : Type} (l : list X) : bool :=&lt;br /&gt;
  beq_nat (length l) 1.&lt;br /&gt;
&lt;br /&gt;
Example test_filter2:&lt;br /&gt;
    filter length_is_1&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      countoddmembers&amp;#039; (l:list nat) : nat &lt;br /&gt;
   tal que countoddmembers&amp;#039; l) es el número de elementos impares de&lt;br /&gt;
   l. Por ejemplo,&lt;br /&gt;
      countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers&amp;#039; [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers&amp;#039; nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers&amp;#039; (l:list nat) : nat :=&lt;br /&gt;
  length (filter oddb l).&lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers&amp;#039;1:   countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;2:   countoddmembers&amp;#039; [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;3:   countoddmembers&amp;#039; nil = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones anónimas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_anon_fun&amp;#039;:&lt;br /&gt;
  doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular&lt;br /&gt;
      filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
             [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_filter2&amp;#039;:&lt;br /&gt;
    filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      filter_even_gt7 (l : list nat) : list nat&lt;br /&gt;
   tal que (filter_even_gt7 l) es la lista de los elemntos de l que son&lt;br /&gt;
   pares y mayores que 7. Por ejemplo,&lt;br /&gt;
      filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
      filter_even_gt7 [5;2;6;19;129]      = [].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition filter_even_gt7 (l : list nat) : list nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_1 :&lt;br /&gt;
  filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_2 :&lt;br /&gt;
  filter_even_gt7 [5;2;6;19;129] = [].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      partition : forall X : Type,&lt;br /&gt;
                  (X -&amp;gt; bool) -&amp;gt; list X -&amp;gt; list X * list X&lt;br /&gt;
   tal que (patition p l) es el par de lista (lx,ly) tal que lx es la&lt;br /&gt;
   lista de los elementos de l que cumplen p y ly la de las que no lo&lt;br /&gt;
   cumplen. Por ejemplo,&lt;br /&gt;
      partition oddb [1;2;3;4;5]         = ([1;3;5], [2;4]).&lt;br /&gt;
      partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition partition {X : Type}&lt;br /&gt;
                     (test : X -&amp;gt; bool)&lt;br /&gt;
                     (l : list X)&lt;br /&gt;
                   : list X * list X&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_partition1: partition oddb [1;2;3;4;5] = ([1;3;5], [2;4]).&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
Example test_partition2: partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Aplicación a todos los elementos (map)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) &lt;br /&gt;
   tal que (map f l) es la lista obtenida aplicando f a todos los&lt;br /&gt;
   elementos de l. Por ejemplo,&lt;br /&gt;
      map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
      map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
      map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
        = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; (f h) :: (map f t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_map1: map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map2:&lt;br /&gt;
  map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map3:&lt;br /&gt;
    map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
  = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      map f (rev l) = rev (map f l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem map_rev : forall (X Y : Type) (f : X -&amp;gt; Y) (l : list X),&lt;br /&gt;
  map f (rev l) = rev (map f l).&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X) : (list Y)&lt;br /&gt;
   tal que (flat_map f l) es la concatenación de las listas obtenidas&lt;br /&gt;
   aplicando f a l. Por ejemplo,&lt;br /&gt;
      flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4] = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X)&lt;br /&gt;
                   : (list Y)&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_flat_map1:&lt;br /&gt;
  flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4]&lt;br /&gt;
  = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X) : option Y&lt;br /&gt;
   tal que (option_map f xo) es la aplicación de f a xo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X)&lt;br /&gt;
                      : option Y :=&lt;br /&gt;
  match xo with&lt;br /&gt;
    | None   =&amp;gt; None&lt;br /&gt;
    | Some x =&amp;gt; Some (f x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Plegados (fold)  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y) : Y&lt;br /&gt;
   tal que (fold f l b) es el plegado de l con la operación f a partir&lt;br /&gt;
   del elemento b. Por ejemplo,&lt;br /&gt;
      fold mult [1;2;3;4] 1                 = 24.&lt;br /&gt;
      fold andb [true;true;false;true] true = false.&lt;br /&gt;
      fold app  [[1];[];[2;3];[4]] []       = [1;2;3;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y)&lt;br /&gt;
                         : Y :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; b&lt;br /&gt;
  | h :: t =&amp;gt; f h (fold f t b)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Check (fold andb).&lt;br /&gt;
(* ===&amp;gt; fold andb : list bool -&amp;gt; bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
Example fold_example1 :&lt;br /&gt;
  fold mult [1;2;3;4] 1 = 24.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example2 :&lt;br /&gt;
  fold andb [true;true;false;true] true = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example3 :&lt;br /&gt;
  fold app  [[1];[];[2;3];[4]] [] = [1;2;3;4].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones que construyen funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      constfun {X: Type} (x: X) : nat-&amp;gt;X&lt;br /&gt;
   tal que (constfun x) es la función que a todos los naturales le&lt;br /&gt;
   asigna el x. Por ejemplo, si se define &lt;br /&gt;
      Definition ftrue := constfun true.&lt;br /&gt;
   entonces,&lt;br /&gt;
      ftrue 0         = true.&lt;br /&gt;
      (constfun 5) 99 = 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition constfun {X: Type} (x: X) : nat-&amp;gt;X :=&lt;br /&gt;
  fun (k:nat) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
Definition ftrue := constfun true.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example1 : ftrue 0 = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example2 : (constfun 5) 99 = 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de plus.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check plus.&lt;br /&gt;
(* ==&amp;gt; nat -&amp;gt; nat -&amp;gt; nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus3 : nat -&amp;gt; nat&lt;br /&gt;
   tal que (plus3 x) es tres más x. Por ejemplo,&lt;br /&gt;
      plus3 4               = 7.&lt;br /&gt;
      doit3times plus3 0    = 9.&lt;br /&gt;
      doit3times (plus 3) 0 = 9.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus3 := plus 3.&lt;br /&gt;
&lt;br /&gt;
Example test_plus3 :    plus3 4 = 7.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039; :   doit3times plus3 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039;&amp;#039; :  doit3times (plus 3) 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
Module Exercises.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_length {X : Type} (l : list X) : nat&lt;br /&gt;
   tal que (fold_length l) es la longitud de l. Por ejemplo,&lt;br /&gt;
      fold_length [4;7;0] = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition fold_length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  fold (fun _ n =&amp;gt; S n) l 0.&lt;br /&gt;
&lt;br /&gt;
Example test_fold_length1 : fold_length [4;7;0] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      fold_length l = length l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fold_length_correct : forall X (l : list X),&lt;br /&gt;
  fold_length l = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y&lt;br /&gt;
   tal que (fold_map f l) es la lista obtenida aplicando f a los&lt;br /&gt;
   elementos de l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que fold_map es equivalente a map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      prod_curry {X Y Z : Type} (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z&lt;br /&gt;
   tal que (prod_curry f x y) es la versión curryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_curry {X Y Z : Type}&lt;br /&gt;
  (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z := f (x, y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      prod_uncurry {X Y Z : Type} (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z&lt;br /&gt;
   tal que (prod_uncurry f p) es la versión incurryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_uncurry {X Y Z : Type}&lt;br /&gt;
  (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Check @prod_curry.&lt;br /&gt;
Check @prod_uncurry.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      prod_curry (prod_uncurry f) x y = f x y&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem uncurry_curry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : X -&amp;gt; Y -&amp;gt; Z)&lt;br /&gt;
                        x y,&lt;br /&gt;
  prod_curry (prod_uncurry f) x y = f x y.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem curry_uncurry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : (X * Y) -&amp;gt; Z) (p : X * Y),&lt;br /&gt;
  prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      forall X n l, length l = n -&amp;gt; @nth_error X l n = None&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. En los siguientes ejercicios se trabajará con la&lt;br /&gt;
   definición de Church de los números naturales: el número natural n es&lt;br /&gt;
   la función que toma como argumento una función f y devuelve como&lt;br /&gt;
   valor la aplicación de n veces la función f. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module Church.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo nat para los números naturales de Church. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition nat := forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      one : nat&lt;br /&gt;
   tal que one es el número uno de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition one : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      two : nat&lt;br /&gt;
   tal que two es el número dos de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition two : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f (f x).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      zero : nat&lt;br /&gt;
   tal que zero es el número cero de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition zero : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      three : nat&lt;br /&gt;
   tal que three es el número tres de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition three : nat := @doit3times.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      succ (n : nat) : nat&lt;br /&gt;
   tal que (succ n) es el siguiente del número n de Church. Por ejemplo, &lt;br /&gt;
      succ zero = one.&lt;br /&gt;
      succ one  = two.&lt;br /&gt;
      succ two  = three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition succ (n : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example succ_1 : succ zero = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example succ_2 : succ one = two.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example succ_3 : succ two = three.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      plus (n m : nat) : nat&lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus zero one             = one.&lt;br /&gt;
      plus two three            = plus three two.&lt;br /&gt;
      plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus (n m : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example plus_1 : plus zero one = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example plus_2 : plus two three = plus three two.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example plus_3 :&lt;br /&gt;
  plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      mult (n m : nat) : nat&lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult one one = one.&lt;br /&gt;
      mult zero (plus three three) = zero.&lt;br /&gt;
      mult two three = plus three three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mult (n m : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example mult_1 : mult one one = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example mult_2 : mult zero (plus three three) = zero.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example mult_3 : mult two three = plus three three.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      exp (n m : nat) : nat&lt;br /&gt;
   tal que (exp n m) es la potencia m-ésima de n. Por ejemplo, &lt;br /&gt;
      exp two two = plus two two.&lt;br /&gt;
      exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
      exp three zero = one.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition exp (n m : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example exp_1 : exp two two = plus two two.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example exp_2 : exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example exp_3 : exp three zero = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
End Church.&lt;br /&gt;
&lt;br /&gt;
End Exercises.&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/SLC2018/index.php?title=Tema_4&amp;diff=104</id>
		<title>Tema 4</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_4&amp;diff=104"/>
		<updated>2018-05-02T22:10:24Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Página creada con &amp;#039;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt; (* T4: Polimorfismo y funciones deo orden superior en Coq *)  Require Export T3_Listas.  (* ===============================================================...&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T4: Polimorfismo y funciones deo orden superior en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T3_Listas.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Polimorfismo&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Listas polimórficas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo boollist para representar las listas de&lt;br /&gt;
   booleanos con los constructores bool_nil y bool_cons tales que &lt;br /&gt;
   + bool_nil es la lista vacía y&lt;br /&gt;
   + (bool_cons x ys) es la lista obtenida añadiendo el booleano x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive boollist : Type :=&lt;br /&gt;
  | bool_nil : boollist&lt;br /&gt;
  | bool_cons : bool -&amp;gt; boollist -&amp;gt; boollist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo (list X) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil es la lista vacía y&lt;br /&gt;
   + (cons x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list (X:Type) : Type :=&lt;br /&gt;
  | nil  : list X&lt;br /&gt;
  | cons : X -&amp;gt; list X -&amp;gt; list X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de list.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check list.&lt;br /&gt;
(* ===&amp;gt; list : Type -&amp;gt; Type *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (nil nat).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (nil nat).&lt;br /&gt;
(* ===&amp;gt; nil nat : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 3 (nil nat)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 3 (nil nat)).&lt;br /&gt;
(* ===&amp;gt; cons nat 3 (nil nat) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check nil.&lt;br /&gt;
(* ===&amp;gt; nil : forall X : Type, list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de cons.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check cons.&lt;br /&gt;
(* ===&amp;gt; cons : forall X : Type, X -&amp;gt; list X -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (cons nat 2 (cons nat 1 (nil nat))).&lt;br /&gt;
(* ==&amp;gt; cons nat 2 (cons nat 1 (nil nat)) : list nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat (X : Type) (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (X : Type) (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0 =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat1 :&lt;br /&gt;
  repeat nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat2 :&lt;br /&gt;
  repeat bool false 1 = cons bool false (nil bool).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Se definen los siguientes tipos&lt;br /&gt;
      Inductive mumble : Type :=&lt;br /&gt;
        | a : mumble&lt;br /&gt;
        | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
        | c : mumble.&lt;br /&gt;
      &lt;br /&gt;
      Inductive grumble (X:Type) : Type :=&lt;br /&gt;
        | d : mumble -&amp;gt; grumble X&lt;br /&gt;
        | e : X -&amp;gt; grumble X.&lt;br /&gt;
  &lt;br /&gt;
   Decidir cuáles de los siguientes expresiones son del tipo (grumble X)&lt;br /&gt;
   para algún X:&lt;br /&gt;
      - [d (b a 5)]&lt;br /&gt;
      - [d mumble (b a 5)]&lt;br /&gt;
      - [d bool (b a 5)]&lt;br /&gt;
      - [e bool true]&lt;br /&gt;
      - [e mumble (b c 0)]&lt;br /&gt;
      - [e bool (b c 0)]&lt;br /&gt;
      - [c]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
Inductive mumble : Type :=&lt;br /&gt;
  | a : mumble&lt;br /&gt;
  | b : mumble -&amp;gt; nat -&amp;gt; mumble&lt;br /&gt;
  | c : mumble.&lt;br /&gt;
&lt;br /&gt;
Inductive grumble (X:Type) : Type :=&lt;br /&gt;
  | d : mumble -&amp;gt; grumble X&lt;br /&gt;
  | e : X -&amp;gt; grumble X.&lt;br /&gt;
&lt;br /&gt;
End MumbleGrumble.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inferencia de tipos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil X&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons X x (repeat&amp;#039; X x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular los tipos de repeat&amp;#039; y repeat.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check repeat&amp;#039;.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
Check repeat.&lt;br /&gt;
(* ===&amp;gt; forall X : Type, X -&amp;gt; nat -&amp;gt; list X *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Síntesis de los tipos de los argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039; X x count : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039; X x count : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil _&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons _ x (repeat&amp;#039;&amp;#039; _ x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123 :=&lt;br /&gt;
  cons nat 1 (cons nat 2 (cons nat 3 (nil nat))).&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039; :=&lt;br /&gt;
  cons _ 1 (cons _ 2 (cons _ 3 (nil _))).&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Argumentos implícitos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Especificar las siguientes funciones y sus argumentos&lt;br /&gt;
   explícitos e implícitos:&lt;br /&gt;
   + nil&lt;br /&gt;
   + constructor&lt;br /&gt;
   + repeat&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Arguments nil {X}.&lt;br /&gt;
Arguments cons {X} _ _.&lt;br /&gt;
Arguments repeat {X} x count.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista formada por los números naturales 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039; := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X&lt;br /&gt;
   tal que (repeat&amp;#039;&amp;#039; X x n) es la lista obtenida repitiendo n veces el&lt;br /&gt;
   elemento x, usando argumentos implícitos. Por ejemplo,&lt;br /&gt;
      repeat&amp;#039;&amp;#039; nat 4 2 = cons nat 4 (cons nat 4 (nil nat)).&lt;br /&gt;
      repeat&amp;#039;&amp;#039; bool false 1 = cons bool false (nil bool).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat&amp;#039;&amp;#039;&amp;#039; {X : Type} (x : X) (count : nat) : list X :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | 0        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; cons x (repeat&amp;#039;&amp;#039;&amp;#039; x count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;1 :&lt;br /&gt;
  repeat&amp;#039;&amp;#039;&amp;#039; 4 2 = cons 4 (cons 4 nil).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_repeat&amp;#039;&amp;#039;&amp;#039;2 :&lt;br /&gt;
  repeat false 1 = cons false nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo (list&amp;#039; {X}) para representar las listas de&lt;br /&gt;
   elementos de con los constructores nil y cons tales que &lt;br /&gt;
   + nil&amp;#039; es la lista vacía y&lt;br /&gt;
   + (cons&amp;#039; x ys) es la lista obtenida añadiendo el elemento x a la&lt;br /&gt;
     lista ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive list&amp;#039; {X:Type} : Type :=&lt;br /&gt;
  | nil&amp;#039;  : list&amp;#039;&lt;br /&gt;
  | cons&amp;#039; : X -&amp;gt; list&amp;#039; -&amp;gt; list&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      app {X : Type} (l1 l2 : list X) : (list X)&lt;br /&gt;
   tal que (app xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint app {X : Type} (l1 l2 : list X) : (list X) :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil      =&amp;gt; l2&lt;br /&gt;
  | cons h t =&amp;gt; cons h (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev {X:Type} (l:list X) : list X&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
      rev (cons true nil) = cons true nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev {X:Type} (l:list X) : list X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil      =&amp;gt; nil&lt;br /&gt;
  | cons h t =&amp;gt; app (rev t) (cons h nil)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1 :&lt;br /&gt;
  rev (cons 1 (cons 2 nil)) = (cons 2 (cons 1 nil)).&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_rev2:&lt;br /&gt;
  rev (cons true nil) = cons true nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length {X : Type} (l : list X) : nat &lt;br /&gt;
   tal que (length xs) es el número de elementos de xs. Por ejemplo,&lt;br /&gt;
      length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil       =&amp;gt; 0&lt;br /&gt;
  | cons _ l&amp;#039; =&amp;gt; S (length l&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_length1:&lt;br /&gt;
  length (cons 1 (cons 2 (cons 3 nil))) = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Explicitación de argumentos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Especificar que la siguiente definición es errónea&lt;br /&gt;
      Fail Definition mynil := nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fail Definition mynil := nil.&lt;br /&gt;
(* ==&amp;gt; Error: Cannot infer the implicit parameter X of nil. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Completar la definición anterior para obtener la lista&lt;br /&gt;
   vacía de números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mynil : list nat := nil.&lt;br /&gt;
&lt;br /&gt;
(* Alternativamente *)&lt;br /&gt;
Definition mynil&amp;#039; := @nil nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir las siguientes abreviaturas&lt;br /&gt;
   + &amp;quot;x :: y&amp;quot;         para (cons x y)&lt;br /&gt;
   + &amp;quot;[ ]&amp;quot;            para nil&lt;br /&gt;
   + &amp;quot;[ x ; .. ; y ]&amp;quot; para (cons x .. (cons y []) ..).&lt;br /&gt;
   + &amp;quot;x ++ y&amp;quot;         para (app x y)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: y&amp;quot; := (cons x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y []) ..).&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition list123&amp;#039;&amp;#039;&amp;#039; := [1; 2; 3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Ejercicios  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall (X:Type), forall l:list X,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la concatenación es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall A (l m n:list A),&lt;br /&gt;
  l ++ m ++ n = (l ++ m) ++ n.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la longitud de una concatenación es la suma de&lt;br /&gt;
   las longitudes de las listas (es decir, es un homomorfismo).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma app_length : forall (X:Type) (l1 l2 : list X),&lt;br /&gt;
  length (l1 ++ l2) = length l1 + length l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_app_distr: forall X (l1 l2 : list X),&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      rev (rev l) = l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall X : Type, forall l : list X,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Polimorfismo de pares  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo prod (X Y) con el constructor pair tal que &lt;br /&gt;
   (pair x y) es el par cuyas componentes son x e y.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive prod (X Y : Type) : Type :=&lt;br /&gt;
| pair : X -&amp;gt; Y -&amp;gt; prod X Y.&lt;br /&gt;
&lt;br /&gt;
Arguments pair {X} {Y} _ _.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;( x , y )&amp;quot; para (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la abreviatura&lt;br /&gt;
      &amp;quot;X * Y&amp;quot; para (prod X Y) &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;X * Y&amp;quot; := (prod X Y) : type_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst {X Y : Type} (p : X * Y) : X&lt;br /&gt;
   tal que (fst p) es la primera componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst {X Y : Type} (p : X * Y) : X :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd {X Y : Type} (p : X * Y) &lt;br /&gt;
   tal que (snd p) es la segunda componente del par p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd {X Y : Type} (p : X * Y) : Y :=&lt;br /&gt;
  match p with&lt;br /&gt;
  | (x, y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) &lt;br /&gt;
   tal que (combine lx ly) es la lista obtenida emparejando los&lt;br /&gt;
   elementos de lx y ly (como zip de Haskell).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint combine {X Y : Type} (lx : list X) (ly : list Y) : list (X*Y) :=&lt;br /&gt;
  match lx, ly with&lt;br /&gt;
  | []     , _       =&amp;gt; []&lt;br /&gt;
  | _      , []      =&amp;gt; []&lt;br /&gt;
  | x :: tx, y :: ty =&amp;gt; (x, y) :: (combine tx ty)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Check combine&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Calcular el resultado de &lt;br /&gt;
      Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (combine [1;2] [false;false;true;true]).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y)&lt;br /&gt;
   tal que (split l) es el par de lista (lx,ly) cuyo emparejamiento es&lt;br /&gt;
   l. (La función split es como unzip de Haskell). Por ejemplo,&lt;br /&gt;
      split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint split {X Y : Type} (l : list (X*Y)) : (list X) * (list Y)&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_split:&lt;br /&gt;
  split [(1,false);(2,false)] = ([1;2],[false;false]).&lt;br /&gt;
Proof.&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Resultados opcionales polimórficos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo (option X) con los constructores Some y None&lt;br /&gt;
   tales que &lt;br /&gt;
   + (Some x) es un valor de tipo X.&lt;br /&gt;
   + None es el valor nulo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive option (X:Type) : Type :=&lt;br /&gt;
  | Some : X -&amp;gt; option X&lt;br /&gt;
  | None : option X.&lt;br /&gt;
&lt;br /&gt;
Arguments Some {X} _.&lt;br /&gt;
Arguments None {X}.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
   tal que (nth_error l n) es el n-ésimo elemento de l. Por ejemplo, &lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
      nth_error [true] 2    = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error {X : Type} (l : list X) (n : nat) : option X :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []      =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O then Some a else nth_error l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [[1];[2]] 1 = Some [2].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [true] 2 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      hd_error {X : Type} (l : list X) : option X&lt;br /&gt;
   tal que (hd_error l) es el primer elemento de l. Por ejemplo,&lt;br /&gt;
      hd_error [1;2]     = Some 1.&lt;br /&gt;
      hd_error [[1];[2]] = Some [1].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error {X : Type} (l : list X) : option X&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Check @hd_error.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [1;2] = Some 1.&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
Example test_hd_error2 : hd_error  [[1];[2]]  = Some [1].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones como datos&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones de orden superior &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X &lt;br /&gt;
   tal que (doit3times f) aplica 3 veces la función f. Por ejemplo,&lt;br /&gt;
      doit3times minustwo 9 = 3.&lt;br /&gt;
      doit3times negb true  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition doit3times {X:Type} (f:X-&amp;gt;X) (n:X) : X :=&lt;br /&gt;
  f (f (f n)).&lt;br /&gt;
&lt;br /&gt;
Check @doit3times.&lt;br /&gt;
(* ===&amp;gt; doit3times : forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X *)&lt;br /&gt;
&lt;br /&gt;
Example test_doit3times: doit3times minustwo 9 = 3.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_doit3times&amp;#039;: doit3times negb true = false.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Filtrado  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      filter {X:Type} (test: X-&amp;gt;bool) (l:list X) : (list X)&lt;br /&gt;
   tal que (filter p l) es la lista de los elementos de l que verifican&lt;br /&gt;
   p. Por ejemplo,&lt;br /&gt;
      filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fixpoint filter {X:Type} (test: X-&amp;gt;bool) (l:list X)&lt;br /&gt;
                : (list X) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; if test h then h :: (filter test t)&lt;br /&gt;
                       else       filter test t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_filter1: filter evenb [1;2;3;4] = [2;4].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Definition length_is_1 {X : Type} (l : list X) : bool :=&lt;br /&gt;
  beq_nat (length l) 1.&lt;br /&gt;
&lt;br /&gt;
Example test_filter2:&lt;br /&gt;
    filter length_is_1&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      countoddmembers&amp;#039; (l:list nat) : nat &lt;br /&gt;
   tal que countoddmembers&amp;#039; l) es el número de elementos impares de&lt;br /&gt;
   l. Por ejemplo,&lt;br /&gt;
      countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers&amp;#039; [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers&amp;#039; nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers&amp;#039; (l:list nat) : nat :=&lt;br /&gt;
  length (filter oddb l).&lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers&amp;#039;1:   countoddmembers&amp;#039; [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;2:   countoddmembers&amp;#039; [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_countoddmembers&amp;#039;3:   countoddmembers&amp;#039; nil = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones anónimas  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_anon_fun&amp;#039;:&lt;br /&gt;
  doit3times (fun n =&amp;gt; n * n) 2 = 256.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular&lt;br /&gt;
      filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
             [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_filter2&amp;#039;:&lt;br /&gt;
    filter (fun l =&amp;gt; beq_nat (length l) 1)&lt;br /&gt;
           [ [1; 2]; [3]; [4]; [5;6;7]; []; [8] ]&lt;br /&gt;
  = [ [3]; [4]; [8] ].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      filter_even_gt7 (l : list nat) : list nat&lt;br /&gt;
   tal que (filter_even_gt7 l) es la lista de los elemntos de l que son&lt;br /&gt;
   pares y mayores que 7. Por ejemplo,&lt;br /&gt;
      filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
      filter_even_gt7 [5;2;6;19;129]      = [].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition filter_even_gt7 (l : list nat) : list nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_1 :&lt;br /&gt;
  filter_even_gt7 [1;2;6;9;10;3;12;8] = [10;12;8].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_filter_even_gt7_2 :&lt;br /&gt;
  filter_even_gt7 [5;2;6;19;129] = [].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      partition : forall X : Type,&lt;br /&gt;
                  (X -&amp;gt; bool) -&amp;gt; list X -&amp;gt; list X * list X&lt;br /&gt;
   tal que (patition p l) es el par de lista (lx,ly) tal que lx es la&lt;br /&gt;
   lista de los elementos de l que cumplen p y ly la de las que no lo&lt;br /&gt;
   cumplen. Por ejemplo,&lt;br /&gt;
      partition oddb [1;2;3;4;5]         = ([1;3;5], [2;4]).&lt;br /&gt;
      partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition partition {X : Type}&lt;br /&gt;
                     (test : X -&amp;gt; bool)&lt;br /&gt;
                     (l : list X)&lt;br /&gt;
                   : list X * list X&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_partition1: partition oddb [1;2;3;4;5] = ([1;3;5], [2;4]).&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
Example test_partition2: partition (fun x =&amp;gt; false) [5;9;0] = ([], [5;9;0]).&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Aplicación a todos los elementos (map)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) &lt;br /&gt;
   tal que (map f l) es la lista obtenida aplicando f a todos los&lt;br /&gt;
   elementos de l. Por ejemplo,&lt;br /&gt;
      map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
      map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
      map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
        = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint map {X Y:Type} (f:X-&amp;gt;Y) (l:list X) : (list Y) :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | []     =&amp;gt; []&lt;br /&gt;
  | h :: t =&amp;gt; (f h) :: (map f t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_map1: map (fun x =&amp;gt; plus 3 x) [2;0;2] = [5;3;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map2:&lt;br /&gt;
  map oddb [2;1;2;5] = [false;true;false;true].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example test_map3:&lt;br /&gt;
    map (fun n =&amp;gt; [evenb n;oddb n]) [2;1;2;5]&lt;br /&gt;
  = [[true;false];[false;true];[true;false];[false;true]].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      map f (rev l) = rev (map f l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem map_rev : forall (X Y : Type) (f : X -&amp;gt; Y) (l : list X),&lt;br /&gt;
  map f (rev l) = rev (map f l).&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X) : (list Y)&lt;br /&gt;
   tal que (flat_map f l) es la concatenación de las listas obtenidas&lt;br /&gt;
   aplicando f a l. Por ejemplo,&lt;br /&gt;
      flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4] = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint flat_map {X Y:Type} (f:X -&amp;gt; list Y) (l:list X)&lt;br /&gt;
                   : (list Y)&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example test_flat_map1:&lt;br /&gt;
  flat_map (fun n =&amp;gt; [n;n;n]) [1;5;4]&lt;br /&gt;
  = [1; 1; 1; 5; 5; 5; 4; 4; 4].&lt;br /&gt;
 (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X) : option Y&lt;br /&gt;
   tal que (option_map f xo) es la aplicación de f a xo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_map {X Y : Type} (f : X -&amp;gt; Y) (xo : option X)&lt;br /&gt;
                      : option Y :=&lt;br /&gt;
  match xo with&lt;br /&gt;
    | None   =&amp;gt; None&lt;br /&gt;
    | Some x =&amp;gt; Some (f x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Plegados (fold)  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y) : Y&lt;br /&gt;
   tal que (fold f l b) es el plegado de l con la operación f a partir&lt;br /&gt;
   del elemento b. Por ejemplo,&lt;br /&gt;
      fold mult [1;2;3;4] 1                 = 24.&lt;br /&gt;
      fold andb [true;true;false;true] true = false.&lt;br /&gt;
      fold app  [[1];[];[2;3];[4]] []       = [1;2;3;4].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint fold {X Y:Type} (f: X-&amp;gt;Y-&amp;gt;Y) (l:list X) (b:Y)&lt;br /&gt;
                         : Y :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; b&lt;br /&gt;
  | h :: t =&amp;gt; f h (fold f t b)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Check (fold andb).&lt;br /&gt;
(* ===&amp;gt; fold andb : list bool -&amp;gt; bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
Example fold_example1 :&lt;br /&gt;
  fold mult [1;2;3;4] 1 = 24.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example2 :&lt;br /&gt;
  fold andb [true;true;false;true] true = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example fold_example3 :&lt;br /&gt;
  fold app  [[1];[];[2;3];[4]] [] = [1;2;3;4].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Funciones que construyen funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      constfun {X: Type} (x: X) : nat-&amp;gt;X&lt;br /&gt;
   tal que (constfun x) es la función que a todos los naturales le&lt;br /&gt;
   asigna el x. Por ejemplo, si se define &lt;br /&gt;
      Definition ftrue := constfun true.&lt;br /&gt;
   entonces,&lt;br /&gt;
      ftrue 0         = true.&lt;br /&gt;
      (constfun 5) 99 = 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition constfun {X: Type} (x: X) : nat-&amp;gt;X :=&lt;br /&gt;
  fun (k:nat) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
Definition ftrue := constfun true.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example1 : ftrue 0 = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Example constfun_example2 : (constfun 5) 99 = 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de plus.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check plus.&lt;br /&gt;
(* ==&amp;gt; nat -&amp;gt; nat -&amp;gt; nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus3 : nat -&amp;gt; nat&lt;br /&gt;
   tal que (plus3 x) es tres más x. Por ejemplo,&lt;br /&gt;
      plus3 4               = 7.&lt;br /&gt;
      doit3times plus3 0    = 9.&lt;br /&gt;
      doit3times (plus 3) 0 = 9.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus3 := plus 3.&lt;br /&gt;
&lt;br /&gt;
Example test_plus3 :    plus3 4 = 7.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039; :   doit3times plus3 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_plus3&amp;#039;&amp;#039; :  doit3times (plus 3) 0 = 9.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
Module Exercises.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_length {X : Type} (l : list X) : nat&lt;br /&gt;
   tal que (fold_length l) es la longitud de l. Por ejemplo,&lt;br /&gt;
      fold_length [4;7;0] = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition fold_length {X : Type} (l : list X) : nat :=&lt;br /&gt;
  fold (fun _ n =&amp;gt; S n) l 0.&lt;br /&gt;
&lt;br /&gt;
Example test_fold_length1 : fold_length [4;7;0] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      fold_length l = length l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fold_length_correct : forall X (l : list X),&lt;br /&gt;
  fold_length l = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
(* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir, usando fold, la función&lt;br /&gt;
      fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y&lt;br /&gt;
   tal que (fold_map f l) es la lista obtenida aplicando f a los&lt;br /&gt;
   elementos de l.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fold_map {X Y:Type} (f : X -&amp;gt; Y) (l : list X) : list Y&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que fold_map es equivalente a map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      prod_curry {X Y Z : Type} (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z&lt;br /&gt;
   tal que (prod_curry f x y) es la versión curryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_curry {X Y Z : Type}&lt;br /&gt;
  (f : X * Y -&amp;gt; Z) (x : X) (y : Y) : Z := f (x, y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      prod_uncurry {X Y Z : Type} (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z&lt;br /&gt;
   tal que (prod_uncurry f p) es la versión incurryficada de f.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition prod_uncurry {X Y Z : Type}&lt;br /&gt;
  (f : X -&amp;gt; Y -&amp;gt; Z) (p : X * Y) : Z&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Check @prod_curry.&lt;br /&gt;
Check @prod_uncurry.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      prod_curry (prod_uncurry f) x y = f x y&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem uncurry_curry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : X -&amp;gt; Y -&amp;gt; Z)&lt;br /&gt;
                        x y,&lt;br /&gt;
  prod_curry (prod_uncurry f) x y = f x y.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem curry_uncurry : forall (X Y Z : Type)&lt;br /&gt;
                        (f : (X * Y) -&amp;gt; Z) (p : X * Y),&lt;br /&gt;
  prod_uncurry (prod_curry f) p = f p.&lt;br /&gt;
Proof.&lt;br /&gt;
  (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      forall X n l, length l = n -&amp;gt; @nth_error X l n = None&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. En los siguientes ejercicios se trabajará con la&lt;br /&gt;
   definición de Church de los números naturales: el número natural n es&lt;br /&gt;
   la función que toma como argumento una función f y devuelve como&lt;br /&gt;
   valor la aplicación de n veces la función f. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module Church.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir el tipo nat para los números naturales de Church. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Definition nat := forall X : Type, (X -&amp;gt; X) -&amp;gt; X -&amp;gt; X.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      one : nat&lt;br /&gt;
   tal que one es el número uno de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition one : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      two : nat&lt;br /&gt;
   tal que two es el número dos de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition two : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; f (f x).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      zero : nat&lt;br /&gt;
   tal que zero es el número cero de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition zero : nat :=&lt;br /&gt;
  fun (X : Type) (f : X -&amp;gt; X) (x : X) =&amp;gt; x.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      three : nat&lt;br /&gt;
   tal que three es el número tres de Church.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition three : nat := @doit3times.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      succ (n : nat) : nat&lt;br /&gt;
   tal que (succ n) es el siguiente del número n de Church. Por ejemplo, &lt;br /&gt;
      succ zero = one.&lt;br /&gt;
      succ one  = two.&lt;br /&gt;
      succ two  = three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition succ (n : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example succ_1 : succ zero = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example succ_2 : succ one = two.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example succ_3 : succ two = three.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      plus (n m : nat) : nat&lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus zero one             = one.&lt;br /&gt;
      plus two three            = plus three two.&lt;br /&gt;
      plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition plus (n m : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example plus_1 : plus zero one = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example plus_2 : plus two three = plus three two.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example plus_3 :&lt;br /&gt;
  plus (plus two two) three = plus one (plus three three).&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      mult (n m : nat) : nat&lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult one one = one.&lt;br /&gt;
      mult zero (plus three three) = zero.&lt;br /&gt;
      mult two three = plus three three.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mult (n m : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example mult_1 : mult one one = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example mult_2 : mult zero (plus three three) = zero.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example mult_3 : mult two three = plus three three.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio. Definir la función&lt;br /&gt;
      exp (n m : nat) : nat&lt;br /&gt;
   tal que (exp n m) es la potencia m-ésima de n. Por ejemplo, &lt;br /&gt;
      exp two two = plus two two.&lt;br /&gt;
      exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
      exp three zero = one.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition exp (n m : nat) : nat&lt;br /&gt;
  (* REPLACE THIS LINE WITH &amp;quot;:= _your_definition_ .&amp;quot; *). Admitted.&lt;br /&gt;
&lt;br /&gt;
Example exp_1 : exp two two = plus two two.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example exp_2 : exp three two = plus (mult two (mult two two)) one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
Example exp_3 : exp three zero = one.&lt;br /&gt;
Proof. (* FILL IN HERE *) Admitted.&lt;br /&gt;
&lt;br /&gt;
End Church.&lt;br /&gt;
(** [] *)&lt;br /&gt;
&lt;br /&gt;
End Exercises.&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/SLC2018/index.php?title=Temas&amp;diff=103</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=103"/>
		<updated>2018-05-02T19:18:33Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
** Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
** Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T3_Listas.v]]).&lt;br /&gt;
** Tema 4: [[Tema 4 | Polimorfismo y orden superior en Coq]].&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=102</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=102"/>
		<updated>2018-05-02T19:16:44Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
** Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
** Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T3_Listas.v]]).&lt;br /&gt;
** Tema 4: [[Tema 4 | Polimorfismo y orden superior en Coq]] ([[Media:T4_PolimorfismoyOS.v | T4_PolimorfismoyOS.v]]).&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=101</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=101"/>
		<updated>2018-04-11T17:31:26Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
** Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
** Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T3_Listas.v]]).&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/apuntes/Soluciones_logicas_de_problemas_logicos/Tema_2.html Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Sistemas&amp;diff=100</id>
		<title>Sistemas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Sistemas&amp;diff=100"/>
		<updated>2018-04-08T06:35:24Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Sistemas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sistemas ==&lt;br /&gt;
&lt;br /&gt;
* Instalación de [https://coq.inria.fr Coq] 8.6&lt;br /&gt;
** [https://github.com/coq/coq/wiki/Installation-of-Coq-on-Linux en Ubuntu].&lt;br /&gt;
** [https://coq.inria.fr/coq-86 en Windows o Mac].&lt;br /&gt;
* Instalación de [https://proofgeneral.github.io/ Proof General]&lt;br /&gt;
* [http://staff.ustc.edu.cn/~xyfeng/teaching/TOPL/reading/ProofGeneral.pdf Guía para instalar Coq y Proof General en Windows]].&lt;br /&gt;
* [http://bit.ly/1Qh8RJB SWISH: SWI-Prolog for SHaring (a SWI-Prolog web IDE)].&lt;br /&gt;
* [http://www.swi-prolog.org/ SWI Prolog].&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Sistemas&amp;diff=99</id>
		<title>Sistemas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Sistemas&amp;diff=99"/>
		<updated>2018-04-05T11:42:01Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Sistemas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Sistemas ==&lt;br /&gt;
&lt;br /&gt;
* Instalación de [https://coq.inria.fr Coq] 8.6&lt;br /&gt;
** [https://github.com/coq/coq/wiki/Installation-of-Coq-on-Linux en Ubuntu].&lt;br /&gt;
** [https://coq.inria.fr/coq-86 en Windows o Mac].&lt;br /&gt;
* Instalación de [https://proofgeneral.github.io/ Proof General]&lt;br /&gt;
* [http://bit.ly/1Qh8RJB SWISH: SWI-Prolog for SHaring (a SWI-Prolog web IDE)].&lt;br /&gt;
* [http://www.swi-prolog.org/ SWI Prolog].&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Documentaci%C3%B3n&amp;diff=98</id>
		<title>Documentación</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Documentaci%C3%B3n&amp;diff=98"/>
		<updated>2018-04-05T11:39:24Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Documentación ==&lt;br /&gt;
&lt;br /&gt;
* [https://softwarefoundations.cis.upenn.edu/lf-current/index.html Software foundations (Volume 1: Logical foundations)]&lt;br /&gt;
* [http://www.seas.upenn.edu/~cis500/current/index.html CIS 500: Software foundations (2017)]&lt;br /&gt;
* [https://www.metalevel.at/prolog The Power of Prolog] ~ M. Triska.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=97</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=97"/>
		<updated>2018-04-05T11:37:19Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Demostración asistida por ordenador con Coq&lt;br /&gt;
** Tema 0: Introducción al Seminario &lt;br /&gt;
*** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
*** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
** Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
** Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T3_Listas.v]]).&lt;br /&gt;
&lt;br /&gt;
* Programación lógica&lt;br /&gt;
** Tema 1: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-13.pdf Introducción a la programación lógica con Prolog].&lt;br /&gt;
** Tema 2: [https://www.cs.us.es/~jalonso/cursos/lmf-12/temas/tema-15 Soluciones lógicas de problemas lógicos].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Archivo:T3_Listas.v&amp;diff=96</id>
		<title>Archivo:T3 Listas.v</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Archivo:T3_Listas.v&amp;diff=96"/>
		<updated>2018-03-25T09:27:20Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=95</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=95"/>
		<updated>2018-03-25T09:26:58Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
* Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
* Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T3_Listas.v]]).&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Archivo:T2_Induccion.v&amp;diff=94</id>
		<title>Archivo:T2 Induccion.v</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Archivo:T2_Induccion.v&amp;diff=94"/>
		<updated>2018-03-25T09:26:39Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=93</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=93"/>
		<updated>2018-03-25T09:26:19Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]]).&lt;br /&gt;
* Tema 2: [[Tema 2 | Demostraciones por inducción en Coq]] ([[Media:T2_Induccion.v |T2_Induccion.v]]).&lt;br /&gt;
* Tema 3: [[Tema 3 | Datos estructurados en Coq]] ([[Media:T3_Listas.v |T2_Listas.v]]).&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Archivo:T1_PF_en_Coq.v&amp;diff=92</id>
		<title>Archivo:T1 PF en Coq.v</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Archivo:T1_PF_en_Coq.v&amp;diff=92"/>
		<updated>2018-03-25T09:22:48Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=91</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=91"/>
		<updated>2018-03-25T09:18:29Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |Teoría]]).&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=90</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=90"/>
		<updated>2018-03-25T09:18:00Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v]]).&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=89</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=89"/>
		<updated>2018-03-25T09:17:26Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] [[Media:T1_PF_en_Coq.v |Enunciado]]&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=88</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=88"/>
		<updated>2018-03-25T09:16:54Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] [[Media:Rel_1.hs |Enunciado]]&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=87</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=87"/>
		<updated>2018-03-25T09:15:55Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v |T1_PF_en_Coq.v]).&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=86</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=86"/>
		<updated>2018-03-25T09:15:22Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]] ([[Media:T1_PF_en_Coq.v|T1_PF_en_Coq.v]).&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=85</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=85"/>
		<updated>2018-03-25T09:10:01Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: [[Tema 1 | Programación funcional en Coq]].&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=84</id>
		<title>Tema 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=84"/>
		<updated>2018-03-25T08:53:56Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T3: Datos estructurados en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T2_Induccion.&lt;br /&gt;
(* La teoría T2_Induccion se encuentra en http://bit.ly/2pDlxlF *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatList. &lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pares de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. El tipo de los números naturales es natprod y su&lt;br /&gt;
   constructor es pair.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natprod : Type :=&lt;br /&gt;
  pair : nat -&amp;gt; nat -&amp;gt; natprod.&lt;br /&gt;
&lt;br /&gt;
Check (pair 3 5).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (fst p) es la primera componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (pair 3 5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (pair 3 5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (snd p) es la segunda componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x,y) como una abreviaura de (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (3,5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (3,5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función fst usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función snd usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      swap_pair : natprod -&amp;gt; natprod&lt;br /&gt;
   tal que (swap_pair p) es el par obtenido intercambiando las&lt;br /&gt;
   componentes de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition swap_pair (p : natprod) : natprod := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; (y,x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todos los naturales&lt;br /&gt;
      (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing&amp;#039; : forall (n m : nat),&lt;br /&gt;
  (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
Proof.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todo par de naturales&lt;br /&gt;
      p = (fst p, snd p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing_stuck : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  simpl. (* No reduce nada. *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros p.  destruct p as [n m].  simpl.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Demostrar que para todo par de naturales p,&lt;br /&gt;
      (snd p, fst p) = swap_pair p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem snd_fst_is_swap : forall (p : natprod),&lt;br /&gt;
  (snd p, fst p) = swap_pair p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Demostrar que para todo par de naturales p,&lt;br /&gt;
      fst (swap_pair p) = snd p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fst_swap_is_snd : forall (p : natprod),&lt;br /&gt;
  fst (swap_pair p) = snd p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Listas de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. natlist es la lista de los números naturales y sus&lt;br /&gt;
   constructores son &lt;br /&gt;
   + nil (la lista vacía) y &lt;br /&gt;
   + cons (tal que (cons x ys) es la lista obtenida añadiéndole x a ys. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natlist : Type :=&lt;br /&gt;
  | nil  : natlist&lt;br /&gt;
  | cons : nat -&amp;gt; natlist -&amp;gt; natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la constante &lt;br /&gt;
      mylist : natlist&lt;br /&gt;
   que es la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x :: ys) como una abreviatura de &lt;br /&gt;
   (cons x ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: l&amp;quot; := (cons x l)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación de las listas finitas escribiendo sus&lt;br /&gt;
   elementos entre corchetes y separados por puntos y comas.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y nil) ..).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Distintas representaciones de mylist.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist1 := 1 :: (2 :: (3 :: nil)).&lt;br /&gt;
Definition mylist2 := 1 :: 2 :: 3 :: nil.&lt;br /&gt;
Definition mylist3 := [1;2;3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Repeat  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat : nat -&amp;gt; nat -&amp;gt; natlist&lt;br /&gt;
   tal que (repeat n k) es la lista formada por k veces el número n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (n count : nat) : natlist :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | O        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; n :: (repeat n count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Length  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (length xs) es el número de elementos de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; O&lt;br /&gt;
  | h :: t =&amp;gt; S (length t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Append  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      append : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (append xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Fixpoint app (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil    =&amp;gt; l2&lt;br /&gt;
  | h :: t =&amp;gt; h :: (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (xs ++ ys) como una abreviaura de &lt;br /&gt;
   (append xs ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (right associativity, at level 60).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
      nil     ++ [4;5] = [4;5].&lt;br /&gt;
      [1;2;3] ++ nil   = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_app1: [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app2: nil ++ [4;5] = [4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app3: [1;2;3] ++ nil = [1;2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Head y tail  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      hd : nat -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (hd d xs) es el primer elemento de xs o d, si xs es la lista&lt;br /&gt;
   vacía. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd (default:nat) (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; default&lt;br /&gt;
  | h :: t =&amp;gt; h&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      tl : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (tl xs) es el resto de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition tl (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
       hd 0 [1;2;3] = 1.&lt;br /&gt;
       hd 0 []      = 0.&lt;br /&gt;
       tl [1;2;3]   = [2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_hd1: hd 0 [1;2;3] = 1.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_hd2: hd 0 [] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_tl: tl [1;2;3] = [2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      nonzeros : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (nonzeros xs) es la lista de los elementos de xs distintos de&lt;br /&gt;
   cero. Por ejemplo,&lt;br /&gt;
      nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | a::bs =&amp;gt; match a with&lt;br /&gt;
            | 0 =&amp;gt; nonzeros bs &lt;br /&gt;
            | _ =&amp;gt;  a:: nonzeros bs end&lt;br /&gt;
 end.&lt;br /&gt;
Example test_nonzeros: nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros2 (l:natlist) : natlist :=&lt;br /&gt;
 match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; if(beq_nat h 0) then nonzeros2 t else h :: nonzeros2 t end.&lt;br /&gt;
&lt;br /&gt;
Example test_nonzeros2: nonzeros2 [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      oddmembers : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (oddmembers xs) es la lista de los elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint oddmembers (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t::xs =&amp;gt; if oddb t then t :: oddmembers xs else oddmembers xs&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example test_oddmembers: oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Definir la función&lt;br /&gt;
      countoddmembers : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (countoddmembers xs) es el número de elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers (l:natlist) : nat :=&lt;br /&gt;
 length (oddmembers l). &lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers1: countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers2: countoddmembers [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers3: countoddmembers nil = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Definir la función&lt;br /&gt;
      alternate : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (alternate xs ys) es la lista obtenida intercalando los&lt;br /&gt;
   elementos de xs e ys. Por ejemplo,&lt;br /&gt;
      alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
      alternate [1] [4;5;6]     = [1;4;5;6].&lt;br /&gt;
      alternate [1;2;3] [4]     = [1;4;2;3].&lt;br /&gt;
      alternate [] [20;30]      = [20;30].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint alternate (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil =&amp;gt; l2&lt;br /&gt;
  | t::xs =&amp;gt; match l2 with&lt;br /&gt;
            | nil =&amp;gt; t::xs&lt;br /&gt;
            | p::ys =&amp;gt; t::p::alternate xs ys end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_alternate1: alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate2: alternate [1] [4;5;6] = [1;4;5;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate3: alternate [1;2;3] [4] = [1;4;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate4: alternate [] [20;30] = [20;30].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Multiconjuntos como listas &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Un multiconjunto es como un conjunto donde los elementos pueden&lt;br /&gt;
   repetirse más de una vez. Podemos implementarlos como listas.  *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo baf de los multiconjuntos de números&lt;br /&gt;
   naturales. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition bag := natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Definir la función&lt;br /&gt;
      count : nat -&amp;gt; bag -&amp;gt; nat &lt;br /&gt;
   tal que (count v s) es el número des veces que aparece el elemento v&lt;br /&gt;
   en el multiconjunto s. Por ejemplo,&lt;br /&gt;
      count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
      count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint count (v:nat) (s:bag) : nat :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil   =&amp;gt; 0&lt;br /&gt;
  | t::xs =&amp;gt; if beq_nat t v&lt;br /&gt;
            then 1 + count v xs&lt;br /&gt;
            else count v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_count1: count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_count2: count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
Proof. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Definir la función&lt;br /&gt;
      sum : bag -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (sum xs ys) es la suma de los multiconjuntos xs e ys. Por&lt;br /&gt;
   ejemplo, &lt;br /&gt;
      count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sum : bag -&amp;gt; bag -&amp;gt; bag := app.&lt;br /&gt;
&lt;br /&gt;
Example test_sum1: count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Definir la función&lt;br /&gt;
      add : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (add x ys) es el multiconjunto obtenido añadiendo el elemento&lt;br /&gt;
   x al multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
      count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition add (v:nat) (s:bag) : bag :=&lt;br /&gt;
  v :: s.&lt;br /&gt;
&lt;br /&gt;
Example test_add1: count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_add2: count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Definir la función&lt;br /&gt;
      member : nat -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (member x ys) se verfica si x pertenece al multiconjunto&lt;br /&gt;
   ys. Por ejemplo,  &lt;br /&gt;
      member 1 [1;4;1] = true.&lt;br /&gt;
      member 2 [1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition member (v:nat) (s:bag) : bool := &lt;br /&gt;
  if beq_nat 0 (count v s)&lt;br /&gt;
  then false&lt;br /&gt;
  else true.&lt;br /&gt;
&lt;br /&gt;
Example test_member1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Definition member2 (v:nat) (s:bag) : bool :=&lt;br /&gt;
  negb (beq_nat O (count v s)).&lt;br /&gt;
&lt;br /&gt;
Example test_member2_1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2_2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. Definir la función&lt;br /&gt;
      remove_one : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_one x ys) es el multiconjunto obtenido eliminando una&lt;br /&gt;
   ocurrencia de x en el multiconjunto ys. Por ejemplo, &lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;1])     = 0.&lt;br /&gt;
      count 4 (remove_one 5 [2;1;4;5;1;4])   = 2.&lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_one (v:nat) (s:bag) : bag :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil     =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then xs&lt;br /&gt;
               else t :: remove_one v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_one1: count 5 (remove_one 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one2: count 5 (remove_one 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one3: count 4 (remove_one 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one4: count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 12. Definir la función&lt;br /&gt;
      remove_all : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_all x ys) es el multiconjunto obtenido eliminando&lt;br /&gt;
   todas las ocurrencias de x en el multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;1])           = 0.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;4;1])             = 0.&lt;br /&gt;
      count 4 (remove_all 5 [2;1;4;5;1;4])         = 2.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_all (v:nat) (s:bag) : bag :=&lt;br /&gt;
   match s with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then remove_all v xs&lt;br /&gt;
               else t :: remove_all v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_all1: count 5 (remove_all 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all2: count 5 (remove_all 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all3: count 4 (remove_all 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all4: count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 13. Definir la función&lt;br /&gt;
      subset : bag -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (subset xs ys) se verifica si xs es un sub,ulticonjunto de&lt;br /&gt;
   ys. Por ejemplo,&lt;br /&gt;
      subset [1;2]   [2;1;4;1] = true.&lt;br /&gt;
      subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint subset (s1:bag) (s2:bag) : bool :=&lt;br /&gt;
  match s1 with&lt;br /&gt;
  | nil   =&amp;gt; true&lt;br /&gt;
  | x::xs =&amp;gt; member x s2 &amp;amp;&amp;amp; subset xs (remove_one x s2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_subset1: subset [1;2] [2;1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_subset2: subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 14. Escribir un teorema sobre multiconjuntos con las funciones&lt;br /&gt;
   count y add y probarlo. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_theorem : forall s1 s2 : bag, forall n : nat,&lt;br /&gt;
  count n s1 + count n s2 = count n (app s1 s2).                 &lt;br /&gt;
Proof.&lt;br /&gt;
  intros s1 s2 n. induction s1 as [|s s&amp;#039;].&lt;br /&gt;
 - simpl. reflexivity.&lt;br /&gt;
 - simpl. destruct (beq_nat s n).&lt;br /&gt;
    + simpl. rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
    + rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Razonamiento sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      [] ++ l = l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem nil_app : forall l:natlist,&lt;br /&gt;
  [] ++ l = l.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      pred (length l) = length (tl l)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem tl_length_pred : forall l:natlist,&lt;br /&gt;
  pred (length l) = length (tl l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. destruct l as [| n l&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons n l&amp;#039; *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Inducción sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la concatenación de listas de naturales es&lt;br /&gt;
   asociativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall l1 l2 l3 : natlist,&lt;br /&gt;
  (l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons n l1&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Comentar los nombres dados en la hipótesis de inducción. *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inversa de una lista  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev [1;2;3] = [3;2;1].&lt;br /&gt;
      rev nil     = nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; rev t ++ [h]&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1: rev [1;2;3] = [3;2;1].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_rev2: rev nil = nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Propiedaes de la función rev  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      length (rev l) = length l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length_firsttry : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = [] *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = n :: l&amp;#039; *)&lt;br /&gt;
    (* Probamos simplificando *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    rewrite &amp;lt;- IHl&amp;#039;.&lt;br /&gt;
    (* Nos encontramos sin más que hacer, así que buscamos un lema que&lt;br /&gt;
       nos ayude. *) &lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem app_length : forall l1 l2 : natlist,&lt;br /&gt;
  length (l1 ++ l2) = (length l1) + (length l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ahora completamos la prueba original. *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; app_length, plus_comm.&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 15. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación de listas. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall l : natlist,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 16. Demostrar que rev es un endomorfismo en (natlist,++)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Theorem rev_app_distr: forall l1 l2 : natlist,&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - simpl. rewrite app_nil_r. reflexivity.&lt;br /&gt;
  - simpl. rewrite HI, app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 17. Demostrar que rev es involutiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall l : natlist,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite rev_app_distr. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 18. Demostrar que&lt;br /&gt;
      l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc4 : forall l1 l2 l3 l4 : natlist,&lt;br /&gt;
  l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3 l4. rewrite app_assoc. rewrite app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 19. Demostrar que al concatenar dos listas no aparecen ni&lt;br /&gt;
   desaparecen ceros. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma nonzeros_app : forall l1 l2 : natlist,&lt;br /&gt;
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 20. Definir la función&lt;br /&gt;
      beq_natlist : natlist -&amp;gt; natlist -&amp;gt; bool&lt;br /&gt;
   tal que (beq_natlist xs ys) se verifica si las listas xs e ys son&lt;br /&gt;
   iguales. Por ejemplo,&lt;br /&gt;
      beq_natlist nil nil         = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;4] = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_natlist (l1 l2 : natlist) : bool:=&lt;br /&gt;
  match l1, l2 with&lt;br /&gt;
  | nil,   nil   =&amp;gt; true&lt;br /&gt;
  | x::xs, y::ys =&amp;gt; beq_nat x y &amp;amp;&amp;amp; beq_natlist xs ys&lt;br /&gt;
  | _, _         =&amp;gt; false&lt;br /&gt;
 end.&lt;br /&gt;
&lt;br /&gt;
Example test_beq_natlist1: (beq_natlist nil nil = true).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist2: beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist3: beq_natlist [1;2;3] [1;2;4] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 21. Demostrar que la igualdad de listas cumple la propiedad&lt;br /&gt;
   reflexiva. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_natlist_refl : forall l:natlist,&lt;br /&gt;
  true = beq_natlist l l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|n xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- HI. replace (beq_nat n n) with true.  reflexivity.&lt;br /&gt;
    + rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 22. Demostrar que al incluir un elemento en un multiconjunto,&lt;br /&gt;
   ese elemento aparece al menos una vez en el resultado.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem count_member_nonzero : forall (s : bag),&lt;br /&gt;
  leb 1 (count 1 (1 :: s)) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
 intro s.  simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 23. Demostrar que cada número natural es menor o igual que&lt;br /&gt;
   su siguiente. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem ble_n_Sn : forall n,&lt;br /&gt;
  leb n (S n) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* 0 *)&lt;br /&gt;
    simpl.  reflexivity.&lt;br /&gt;
  - (* S n&amp;#039; *)&lt;br /&gt;
    simpl.  rewrite IHn&amp;#039;.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 24. Demostrar que al borrar una ocurrencia de 0 de un&lt;br /&gt;
   multiconjunto el número de ocurrencias de 0 en el resultado es menor&lt;br /&gt;
   o igual que en el original.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem remove_decreases_count: forall (s : bag),&lt;br /&gt;
  leb (count 0 (remove_one 0 s)) (count 0 s) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction s as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite ble_n_Sn. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.    &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 25. Escribir un teorema con las funciones count y sum de los&lt;br /&gt;
   multiconjuntos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_count_sum: forall n : nat, forall b1 b2 : bag,&lt;br /&gt;
  count n b1 + count n b2 = count n (sum b1 b2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n b1 b2. induction b1 as [|b bs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct (beq_nat b n).&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 26. Demostrar que la función rev es inyectiva; es decir,&lt;br /&gt;
      forall (l1 l2 : natlist), rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_injective : forall (l1 l2 : natlist),&lt;br /&gt;
  rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros. rewrite &amp;lt;- rev_involutive, &amp;lt;- H, rev_involutive. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Opcionales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_bad : natlist -&amp;gt; n -&amp;gt; nat&lt;br /&gt;
   tal que (nth_bad xs n) es el n-ésimo elemento de la lista xs y 42 si&lt;br /&gt;
   la lista tiene menos de n elementos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_bad (l:natlist) (n:nat) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; 42  (* un valor arbitrario *)&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; a&lt;br /&gt;
               | false =&amp;gt; nth_bad l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo natoption con los contructores&lt;br /&gt;
      Some : nat -&amp;gt; natoption&lt;br /&gt;
      None : natoption.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natoption : Type :=&lt;br /&gt;
  | Some : nat -&amp;gt; natoption&lt;br /&gt;
  | None : natoption.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_error : natlist -&amp;gt; nat -&amp;gt; natoption&lt;br /&gt;
   tal que (nth_error xs n) es el n-ésimo elemento de la lista xs o None&lt;br /&gt;
   si la lista tiene menos de n elementos. Por ejemplo,&lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
      nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; Some a&lt;br /&gt;
               | false =&amp;gt; nth_error l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* Introduciendo condicionales nos queda: *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error&amp;#039; (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O&lt;br /&gt;
               then Some a&lt;br /&gt;
               else nth_error&amp;#039; l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* Nota: Los condicionales funcionan sobre todo tipo inductivo con dos &lt;br /&gt;
   constructores en Coq, sin booleanos. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      option_elim nat -&amp;gt; natoption -&amp;gt; nat&lt;br /&gt;
   tal que (option_elim d o) es el valor de o, si o tienve valor o es d&lt;br /&gt;
   en caso contrario.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_elim (d : nat) (o : natoption) : nat :=&lt;br /&gt;
  match o with&lt;br /&gt;
  | Some n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  | None =&amp;gt; d&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 27. Definir la función&lt;br /&gt;
      hd_error : natlist -&amp;gt; natoption&lt;br /&gt;
   tal que (hd_error xs) es el primer elemento de xs, si xs es no vacía;&lt;br /&gt;
   o es None, en caso contrario. Por ejemplo,&lt;br /&gt;
      hd_error []    = None.&lt;br /&gt;
      hd_error [1]   = Some 1.&lt;br /&gt;
      hd_error [5;6] = Some 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error (l : natlist) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil   =&amp;gt; None&lt;br /&gt;
  | x::xs =&amp;gt; Some x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [] = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error2 : hd_error [1] = Some 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error3 : hd_error [5;6] = Some 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 28. Demostrar que&lt;br /&gt;
      hd default l = option_elim default (hd_error l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem option_elim_hd : forall (l:natlist) (default:nat),&lt;br /&gt;
  hd default l = option_elim default (hd_error l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l default. destruct l as [|x xs].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatList.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones parciales (o diccionarios)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo id con el constructor&lt;br /&gt;
      Id : nat -&amp;gt; id.&lt;br /&gt;
   La idea es usarlo como clave de los dicccionarios.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive id : Type :=&lt;br /&gt;
  | Id : nat -&amp;gt; id.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_id : id -&amp;gt; id -&amp;gt; bool&lt;br /&gt;
   tal que  (beq_id x1 x2) se verifcia si tienen la misma clave.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition beq_id (x1 x2 : id) :=&lt;br /&gt;
  match x1, x2 with&lt;br /&gt;
  | Id n1, Id n2 =&amp;gt; beq_nat n1 n2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 29. Demostrar que beq_id es reflexiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_id_refl : forall x, true = beq_id x x.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro x. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo PartialMap que importa a NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module PartialMap.&lt;br /&gt;
Export NatList.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo partial_map (para representar los&lt;br /&gt;
   diccionarios) con los contructores&lt;br /&gt;
      empty  : partial_map&lt;br /&gt;
      record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive partial_map : Type :=&lt;br /&gt;
  | empty  : partial_map&lt;br /&gt;
  | record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      update : partial_map -&amp;gt; id -&amp;gt; nat -&amp;gt; partial_map&lt;br /&gt;
   tal que (update d i v) es el diccionario obtenido a partir del d&lt;br /&gt;
   + si d tiene un elemento con clave i, le cambia su valor a v&lt;br /&gt;
   + en caso contrario, le añade el elemento v con clave i &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition update (d : partial_map)&lt;br /&gt;
                  (x : id) (value : nat)&lt;br /&gt;
                  : partial_map :=&lt;br /&gt;
  record x value d.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      find : id -&amp;gt; partial_map -&amp;gt; natoption &lt;br /&gt;
   tal que (find i d) es el valor de la entrada de d con clave i, o None&lt;br /&gt;
   si d no tiene ninguna entrada con clave i.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint find (x : id) (d : partial_map) : natoption :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | empty         =&amp;gt; None&lt;br /&gt;
  | record y v d&amp;#039; =&amp;gt; if beq_id x y&lt;br /&gt;
                     then Some v&lt;br /&gt;
                     else find x d&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 30. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
        find x (update d x v) = Some v.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_eq :&lt;br /&gt;
  forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
    find x (update d x v) = Some v.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x v. destruct d as [|d&amp;#039; x&amp;#039; v&amp;#039;].&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 31. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
        beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_neq :&lt;br /&gt;
  forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
    beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x y o p. simpl. rewrite p. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizr el módulo PartialMap&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End PartialMap.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 32. Se define el tipo baz por&lt;br /&gt;
      Inductive baz : Type :=&lt;br /&gt;
        | Baz1 : baz -&amp;gt; baz&lt;br /&gt;
        | Baz2 : baz -&amp;gt; bool -&amp;gt; baz.&lt;br /&gt;
   ¿Cuántos elementos tiene el tipo baz?&lt;br /&gt;
   ------------------------------------------------------------------ *)&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/SLC2018/index.php?title=Tema_3&amp;diff=83</id>
		<title>Tema 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=83"/>
		<updated>2018-03-25T08:40:42Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T3: Datos estructurados en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export T2_Induccion.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatList. &lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pares de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. El tipo de los números naturales es natprod y su&lt;br /&gt;
   constructor es pair.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natprod : Type :=&lt;br /&gt;
  pair : nat -&amp;gt; nat -&amp;gt; natprod.&lt;br /&gt;
&lt;br /&gt;
Check (pair 3 5).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (fst p) es la primera componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (pair 3 5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (pair 3 5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (snd p) es la segunda componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x,y) como una abreviaura de (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (3,5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (3,5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función fst usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función snd usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      swap_pair : natprod -&amp;gt; natprod&lt;br /&gt;
   tal que (swap_pair p) es el par obtenido intercambiando las&lt;br /&gt;
   componentes de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition swap_pair (p : natprod) : natprod := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; (y,x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todos los naturales&lt;br /&gt;
      (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing&amp;#039; : forall (n m : nat),&lt;br /&gt;
  (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
Proof.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todo par de naturales&lt;br /&gt;
      p = (fst p, snd p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing_stuck : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  simpl. (* No reduce nada. *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros p.  destruct p as [n m].  simpl.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Demostrar que para todo par de naturales p,&lt;br /&gt;
      (snd p, fst p) = swap_pair p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem snd_fst_is_swap : forall (p : natprod),&lt;br /&gt;
  (snd p, fst p) = swap_pair p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Demostrar que para todo par de naturales p,&lt;br /&gt;
      fst (swap_pair p) = snd p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fst_swap_is_snd : forall (p : natprod),&lt;br /&gt;
  fst (swap_pair p) = snd p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Listas de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. natlist es la lista de los números naturales y sus&lt;br /&gt;
   constructores son &lt;br /&gt;
   + nil (la lista vacía) y &lt;br /&gt;
   + cons (tal que (cons x ys) es la lista obtenida añadiéndole x a ys. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natlist : Type :=&lt;br /&gt;
  | nil  : natlist&lt;br /&gt;
  | cons : nat -&amp;gt; natlist -&amp;gt; natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la constante &lt;br /&gt;
      mylist : natlist&lt;br /&gt;
   que es la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x :: ys) como una abreviatura de &lt;br /&gt;
   (cons x ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: l&amp;quot; := (cons x l)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación de las listas finitas escribiendo sus&lt;br /&gt;
   elementos entre corchetes y separados por puntos y comas.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y nil) ..).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Distintas representaciones de mylist.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist1 := 1 :: (2 :: (3 :: nil)).&lt;br /&gt;
Definition mylist2 := 1 :: 2 :: 3 :: nil.&lt;br /&gt;
Definition mylist3 := [1;2;3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Repeat  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat : nat -&amp;gt; nat -&amp;gt; natlist&lt;br /&gt;
   tal que (repeat n k) es la lista formada por k veces el número n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (n count : nat) : natlist :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | O        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; n :: (repeat n count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Length  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (length xs) es el número de elementos de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; O&lt;br /&gt;
  | h :: t =&amp;gt; S (length t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Append  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      append : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (append xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Fixpoint app (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil    =&amp;gt; l2&lt;br /&gt;
  | h :: t =&amp;gt; h :: (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (xs ++ ys) como una abreviaura de &lt;br /&gt;
   (append xs ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (right associativity, at level 60).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
      nil     ++ [4;5] = [4;5].&lt;br /&gt;
      [1;2;3] ++ nil   = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_app1: [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app2: nil ++ [4;5] = [4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app3: [1;2;3] ++ nil = [1;2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Head y tail  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      hd : nat -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (hd d xs) es el primer elemento de xs o d, si xs es la lista&lt;br /&gt;
   vacía. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd (default:nat) (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; default&lt;br /&gt;
  | h :: t =&amp;gt; h&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      tl : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (tl xs) es el resto de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition tl (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
       hd 0 [1;2;3] = 1.&lt;br /&gt;
       hd 0 []      = 0.&lt;br /&gt;
       tl [1;2;3]   = [2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_hd1: hd 0 [1;2;3] = 1.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_hd2: hd 0 [] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_tl: tl [1;2;3] = [2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      nonzeros : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (nonzeros xs) es la lista de los elementos de xs distintos de&lt;br /&gt;
   cero. Por ejemplo,&lt;br /&gt;
      nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | a::bs =&amp;gt; match a with&lt;br /&gt;
            | 0 =&amp;gt; nonzeros bs &lt;br /&gt;
            | _ =&amp;gt;  a:: nonzeros bs end&lt;br /&gt;
 end.&lt;br /&gt;
Example test_nonzeros: nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros2 (l:natlist) : natlist :=&lt;br /&gt;
 match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; if(beq_nat h 0) then nonzeros2 t else h :: nonzeros2 t end.&lt;br /&gt;
&lt;br /&gt;
Example test_nonzeros2: nonzeros2 [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      oddmembers : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (oddmembers xs) es la lista de los elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint oddmembers (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t::xs =&amp;gt; if oddb t then t :: oddmembers xs else oddmembers xs&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example test_oddmembers: oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Definir la función&lt;br /&gt;
      countoddmembers : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (countoddmembers xs) es el número de elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers (l:natlist) : nat :=&lt;br /&gt;
 length (oddmembers l). &lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers1: countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers2: countoddmembers [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers3: countoddmembers nil = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Definir la función&lt;br /&gt;
      alternate : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (alternate xs ys) es la lista obtenida intercalando los&lt;br /&gt;
   elementos de xs e ys. Por ejemplo,&lt;br /&gt;
      alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
      alternate [1] [4;5;6]     = [1;4;5;6].&lt;br /&gt;
      alternate [1;2;3] [4]     = [1;4;2;3].&lt;br /&gt;
      alternate [] [20;30]      = [20;30].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint alternate (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil =&amp;gt; l2&lt;br /&gt;
  | t::xs =&amp;gt; match l2 with&lt;br /&gt;
            | nil =&amp;gt; t::xs&lt;br /&gt;
            | p::ys =&amp;gt; t::p::alternate xs ys end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_alternate1: alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate2: alternate [1] [4;5;6] = [1;4;5;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate3: alternate [1;2;3] [4] = [1;4;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate4: alternate [] [20;30] = [20;30].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Multiconjuntos como listas &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Un multiconjunto es como un conjunto donde los elementos pueden&lt;br /&gt;
   repetirse más de una vez. Podemos implementarlos como listas.  *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo baf de los multiconjuntos de números&lt;br /&gt;
   naturales. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition bag := natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Definir la función&lt;br /&gt;
      count : nat -&amp;gt; bag -&amp;gt; nat &lt;br /&gt;
   tal que (count v s) es el número des veces que aparece el elemento v&lt;br /&gt;
   en el multiconjunto s. Por ejemplo,&lt;br /&gt;
      count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
      count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint count (v:nat) (s:bag) : nat :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil   =&amp;gt; 0&lt;br /&gt;
  | t::xs =&amp;gt; if beq_nat t v&lt;br /&gt;
            then 1 + count v xs&lt;br /&gt;
            else count v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_count1: count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_count2: count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
Proof. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Definir la función&lt;br /&gt;
      sum : bag -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (sum xs ys) es la suma de los multiconjuntos xs e ys. Por&lt;br /&gt;
   ejemplo, &lt;br /&gt;
      count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sum : bag -&amp;gt; bag -&amp;gt; bag := app.&lt;br /&gt;
&lt;br /&gt;
Example test_sum1: count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Definir la función&lt;br /&gt;
      add : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (add x ys) es el multiconjunto obtenido añadiendo el elemento&lt;br /&gt;
   x al multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
      count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition add (v:nat) (s:bag) : bag :=&lt;br /&gt;
  v :: s.&lt;br /&gt;
&lt;br /&gt;
Example test_add1: count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_add2: count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Definir la función&lt;br /&gt;
      member : nat -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (member x ys) se verfica si x pertenece al multiconjunto&lt;br /&gt;
   ys. Por ejemplo,  &lt;br /&gt;
      member 1 [1;4;1] = true.&lt;br /&gt;
      member 2 [1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition member (v:nat) (s:bag) : bool := &lt;br /&gt;
  if beq_nat 0 (count v s)&lt;br /&gt;
  then false&lt;br /&gt;
  else true.&lt;br /&gt;
&lt;br /&gt;
Example test_member1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Definition member2 (v:nat) (s:bag) : bool :=&lt;br /&gt;
  negb (beq_nat O (count v s)).&lt;br /&gt;
&lt;br /&gt;
Example test_member2_1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2_2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. Definir la función&lt;br /&gt;
      remove_one : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_one x ys) es el multiconjunto obtenido eliminando una&lt;br /&gt;
   ocurrencia de x en el multiconjunto ys. Por ejemplo, &lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;1])     = 0.&lt;br /&gt;
      count 4 (remove_one 5 [2;1;4;5;1;4])   = 2.&lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_one (v:nat) (s:bag) : bag :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil     =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then xs&lt;br /&gt;
               else t :: remove_one v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_one1: count 5 (remove_one 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one2: count 5 (remove_one 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one3: count 4 (remove_one 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one4: count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 12. Definir la función&lt;br /&gt;
      remove_all : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_all x ys) es el multiconjunto obtenido eliminando&lt;br /&gt;
   todas las ocurrencias de x en el multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;1])           = 0.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;4;1])             = 0.&lt;br /&gt;
      count 4 (remove_all 5 [2;1;4;5;1;4])         = 2.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_all (v:nat) (s:bag) : bag :=&lt;br /&gt;
   match s with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then remove_all v xs&lt;br /&gt;
               else t :: remove_all v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_all1: count 5 (remove_all 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all2: count 5 (remove_all 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all3: count 4 (remove_all 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all4: count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 13. Definir la función&lt;br /&gt;
      subset : bag -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (subset xs ys) se verifica si xs es un sub,ulticonjunto de&lt;br /&gt;
   ys. Por ejemplo,&lt;br /&gt;
      subset [1;2]   [2;1;4;1] = true.&lt;br /&gt;
      subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint subset (s1:bag) (s2:bag) : bool :=&lt;br /&gt;
  match s1 with&lt;br /&gt;
  | nil   =&amp;gt; true&lt;br /&gt;
  | x::xs =&amp;gt; member x s2 &amp;amp;&amp;amp; subset xs (remove_one x s2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_subset1: subset [1;2] [2;1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_subset2: subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 14. Escribir un teorema sobre multiconjuntos con las funciones&lt;br /&gt;
   count y add y probarlo. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_theorem : forall s1 s2 : bag, forall n : nat,&lt;br /&gt;
  count n s1 + count n s2 = count n (app s1 s2).                 &lt;br /&gt;
Proof.&lt;br /&gt;
  intros s1 s2 n. induction s1 as [|s s&amp;#039;].&lt;br /&gt;
 - simpl. reflexivity.&lt;br /&gt;
 - simpl. destruct (beq_nat s n).&lt;br /&gt;
    + simpl. rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
    + rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Razonamiento sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      [] ++ l = l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem nil_app : forall l:natlist,&lt;br /&gt;
  [] ++ l = l.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      pred (length l) = length (tl l)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem tl_length_pred : forall l:natlist,&lt;br /&gt;
  pred (length l) = length (tl l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. destruct l as [| n l&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons n l&amp;#039; *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Inducción sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la concatenación de listas de naturales es&lt;br /&gt;
   asociativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall l1 l2 l3 : natlist,&lt;br /&gt;
  (l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons n l1&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Comentar los nombres dados en la hipótesis de inducción. *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inversa de una lista  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev [1;2;3] = [3;2;1].&lt;br /&gt;
      rev nil     = nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; rev t ++ [h]&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1: rev [1;2;3] = [3;2;1].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_rev2: rev nil = nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Propiedaes de la función rev  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      length (rev l) = length l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length_firsttry : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = [] *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = n :: l&amp;#039; *)&lt;br /&gt;
    (* Probamos simplificando *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    rewrite &amp;lt;- IHl&amp;#039;.&lt;br /&gt;
    (* Nos encontramos sin más que hacer, así que buscamos un lema que&lt;br /&gt;
       nos ayude. *) &lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem app_length : forall l1 l2 : natlist,&lt;br /&gt;
  length (l1 ++ l2) = (length l1) + (length l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ahora completamos la prueba original. *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; app_length, plus_comm.&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 15. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación de listas. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall l : natlist,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 16. Demostrar que rev es un endomorfismo en (natlist,++)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Theorem rev_app_distr: forall l1 l2 : natlist,&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - simpl. rewrite app_nil_r. reflexivity.&lt;br /&gt;
  - simpl. rewrite HI, app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 17. Demostrar que rev es involutiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall l : natlist,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite rev_app_distr. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 18. Demostrar que&lt;br /&gt;
      l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc4 : forall l1 l2 l3 l4 : natlist,&lt;br /&gt;
  l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3 l4. rewrite app_assoc. rewrite app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 19. Demostrar que al concatenar dos listas no aparecen ni&lt;br /&gt;
   desaparecen ceros. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma nonzeros_app : forall l1 l2 : natlist,&lt;br /&gt;
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 20. Definir la función&lt;br /&gt;
      beq_natlist : natlist -&amp;gt; natlist -&amp;gt; bool&lt;br /&gt;
   tal que (beq_natlist xs ys) se verifica si las listas xs e ys son&lt;br /&gt;
   iguales. Por ejemplo,&lt;br /&gt;
      beq_natlist nil nil         = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;4] = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_natlist (l1 l2 : natlist) : bool:=&lt;br /&gt;
  match l1, l2 with&lt;br /&gt;
  | nil,   nil   =&amp;gt; true&lt;br /&gt;
  | x::xs, y::ys =&amp;gt; beq_nat x y &amp;amp;&amp;amp; beq_natlist xs ys&lt;br /&gt;
  | _, _         =&amp;gt; false&lt;br /&gt;
 end.&lt;br /&gt;
&lt;br /&gt;
Example test_beq_natlist1: (beq_natlist nil nil = true).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist2: beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist3: beq_natlist [1;2;3] [1;2;4] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 21. Demostrar que la igualdad de listas cumple la propiedad&lt;br /&gt;
   reflexiva. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_natlist_refl : forall l:natlist,&lt;br /&gt;
  true = beq_natlist l l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|n xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- HI. replace (beq_nat n n) with true.  reflexivity.&lt;br /&gt;
    + rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 22. Demostrar que al incluir un elemento en un multiconjunto,&lt;br /&gt;
   ese elemento aparece al menos una vez en el resultado.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem count_member_nonzero : forall (s : bag),&lt;br /&gt;
  leb 1 (count 1 (1 :: s)) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
 intro s.  simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 23. Demostrar que cada número natural es menor o igual que&lt;br /&gt;
   su siguiente. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem ble_n_Sn : forall n,&lt;br /&gt;
  leb n (S n) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* 0 *)&lt;br /&gt;
    simpl.  reflexivity.&lt;br /&gt;
  - (* S n&amp;#039; *)&lt;br /&gt;
    simpl.  rewrite IHn&amp;#039;.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 24. Demostrar que al borrar una ocurrencia de 0 de un&lt;br /&gt;
   multiconjunto el número de ocurrencias de 0 en el resultado es menor&lt;br /&gt;
   o igual que en el original.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem remove_decreases_count: forall (s : bag),&lt;br /&gt;
  leb (count 0 (remove_one 0 s)) (count 0 s) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction s as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite ble_n_Sn. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.    &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 25. Escribir un teorema con las funciones count y sum de los&lt;br /&gt;
   multiconjuntos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_count_sum: forall n : nat, forall b1 b2 : bag,&lt;br /&gt;
  count n b1 + count n b2 = count n (sum b1 b2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n b1 b2. induction b1 as [|b bs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct (beq_nat b n).&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 26. Demostrar que la función rev es inyectiva; es decir,&lt;br /&gt;
      forall (l1 l2 : natlist), rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_injective : forall (l1 l2 : natlist),&lt;br /&gt;
  rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros. rewrite &amp;lt;- rev_involutive, &amp;lt;- H, rev_involutive. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Opcionales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_bad : natlist -&amp;gt; n -&amp;gt; nat&lt;br /&gt;
   tal que (nth_bad xs n) es el n-ésimo elemento de la lista xs y 42 si&lt;br /&gt;
   la lista tiene menos de n elementos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_bad (l:natlist) (n:nat) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; 42  (* un valor arbitrario *)&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; a&lt;br /&gt;
               | false =&amp;gt; nth_bad l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo natoption con los contructores&lt;br /&gt;
      Some : nat -&amp;gt; natoption&lt;br /&gt;
      None : natoption.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natoption : Type :=&lt;br /&gt;
  | Some : nat -&amp;gt; natoption&lt;br /&gt;
  | None : natoption.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_error : natlist -&amp;gt; nat -&amp;gt; natoption&lt;br /&gt;
   tal que (nth_error xs n) es el n-ésimo elemento de la lista xs o None&lt;br /&gt;
   si la lista tiene menos de n elementos. Por ejemplo,&lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
      nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; Some a&lt;br /&gt;
               | false =&amp;gt; nth_error l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* Introduciendo condicionales nos queda: *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error&amp;#039; (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O&lt;br /&gt;
               then Some a&lt;br /&gt;
               else nth_error&amp;#039; l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* Nota: Los condicionales funcionan sobre todo tipo inductivo con dos &lt;br /&gt;
   constructores en Coq, sin booleanos. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      option_elim nat -&amp;gt; natoption -&amp;gt; nat&lt;br /&gt;
   tal que (option_elim d o) es el valor de o, si o tienve valor o es d&lt;br /&gt;
   en caso contrario.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_elim (d : nat) (o : natoption) : nat :=&lt;br /&gt;
  match o with&lt;br /&gt;
  | Some n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  | None =&amp;gt; d&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 27. Definir la función&lt;br /&gt;
      hd_error : natlist -&amp;gt; natoption&lt;br /&gt;
   tal que (hd_error xs) es el primer elemento de xs, si xs es no vacía;&lt;br /&gt;
   o es None, en caso contrario. Por ejemplo,&lt;br /&gt;
      hd_error []    = None.&lt;br /&gt;
      hd_error [1]   = Some 1.&lt;br /&gt;
      hd_error [5;6] = Some 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error (l : natlist) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil   =&amp;gt; None&lt;br /&gt;
  | x::xs =&amp;gt; Some x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [] = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error2 : hd_error [1] = Some 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error3 : hd_error [5;6] = Some 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 28. Demostrar que&lt;br /&gt;
      hd default l = option_elim default (hd_error l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem option_elim_hd : forall (l:natlist) (default:nat),&lt;br /&gt;
  hd default l = option_elim default (hd_error l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l default. destruct l as [|x xs].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatList.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones parciales (o diccionarios)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo id con el constructor&lt;br /&gt;
      Id : nat -&amp;gt; id.&lt;br /&gt;
   La idea es usarlo como clave de los dicccionarios.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive id : Type :=&lt;br /&gt;
  | Id : nat -&amp;gt; id.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_id : id -&amp;gt; id -&amp;gt; bool&lt;br /&gt;
   tal que  (beq_id x1 x2) se verifcia si tienen la misma clave.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition beq_id (x1 x2 : id) :=&lt;br /&gt;
  match x1, x2 with&lt;br /&gt;
  | Id n1, Id n2 =&amp;gt; beq_nat n1 n2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 29. Demostrar que beq_id es reflexiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_id_refl : forall x, true = beq_id x x.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro x. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo PartialMap que importa a NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module PartialMap.&lt;br /&gt;
Export NatList.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo partial_map (para representar los&lt;br /&gt;
   diccionarios) con los contructores&lt;br /&gt;
      empty  : partial_map&lt;br /&gt;
      record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive partial_map : Type :=&lt;br /&gt;
  | empty  : partial_map&lt;br /&gt;
  | record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      update : partial_map -&amp;gt; id -&amp;gt; nat -&amp;gt; partial_map&lt;br /&gt;
   tal que (update d i v) es el diccionario obtenido a partir del d&lt;br /&gt;
   + si d tiene un elemento con clave i, le cambia su valor a v&lt;br /&gt;
   + en caso contrario, le añade el elemento v con clave i &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition update (d : partial_map)&lt;br /&gt;
                  (x : id) (value : nat)&lt;br /&gt;
                  : partial_map :=&lt;br /&gt;
  record x value d.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      find : id -&amp;gt; partial_map -&amp;gt; natoption &lt;br /&gt;
   tal que (find i d) es el valor de la entrada de d con clave i, o None&lt;br /&gt;
   si d no tiene ninguna entrada con clave i.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint find (x : id) (d : partial_map) : natoption :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | empty         =&amp;gt; None&lt;br /&gt;
  | record y v d&amp;#039; =&amp;gt; if beq_id x y&lt;br /&gt;
                     then Some v&lt;br /&gt;
                     else find x d&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 30. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
        find x (update d x v) = Some v.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_eq :&lt;br /&gt;
  forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
    find x (update d x v) = Some v.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x v. destruct d as [|d&amp;#039; x&amp;#039; v&amp;#039;].&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 31. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
        beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_neq :&lt;br /&gt;
  forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
    beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x y o p. simpl. rewrite p. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizr el módulo PartialMap&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End PartialMap.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 32. Se define el tipo baz por&lt;br /&gt;
      Inductive baz : Type :=&lt;br /&gt;
        | Baz1 : baz -&amp;gt; baz&lt;br /&gt;
        | Baz2 : baz -&amp;gt; bool -&amp;gt; baz.&lt;br /&gt;
   ¿Cuántos elementos tiene el tipo baz?&lt;br /&gt;
   ------------------------------------------------------------------ *)&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/SLC2018/index.php?title=Temas&amp;diff=82</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=82"/>
		<updated>2018-03-25T08:34:15Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Protegió «Temas» ([edit=sysop] (indefinido) [move=sysop] (indefinido))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: Programación funcional en Coq&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_2&amp;diff=81</id>
		<title>Tema 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_2&amp;diff=81"/>
		<updated>2018-03-25T08:34:04Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Protegió «Tema 2» ([edit=sysop] (indefinido) [move=sysop] (indefinido))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T2: Demostraciones por inducción en Coq *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de importación de teorías *)&lt;br /&gt;
Require Export T1_PF_en_Coq.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pruebas por inducción &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de demostración que no puede ser realizada por el método &lt;br /&gt;
   simple  *) &lt;br /&gt;
Theorem plus_n_O_firsttry : forall n:nat,&lt;br /&gt;
  n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  simpl. (* ¡¡¡No hace nada!!! *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem plus_n_O_secondtry : forall n:nat,&lt;br /&gt;
  n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n as [| n&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    reflexivity. (* Hasta aquí todo bien ... *)&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl.       (* ... pero otra vez no hacemos nada *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba por inducción de n = n + 0. *)&lt;br /&gt;
Theorem plus_n_O : forall n:nat, n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)    reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *) simpl. rewrite &amp;lt;- IHn&amp;#039;. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba por inducción de (minus n n = 0). *)&lt;br /&gt;
Theorem minus_diag : forall n,&lt;br /&gt;
  minus n n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    simpl. reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.1. Demostrar que &lt;br /&gt;
      forall n:nat, n * 0 = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_0_r : forall n:nat,&lt;br /&gt;
  n * 0 = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.2. Demostrar que &lt;br /&gt;
      forall n m : nat, S (n + m) = n + (S m).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_n_Sm : forall n m : nat,&lt;br /&gt;
  S (n + m) = n + (S m).&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.3. Demostrar que &lt;br /&gt;
      forall n m : nat, n + m = m + n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_comm : forall n m : nat,&lt;br /&gt;
  n + m = m + n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros  n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. rewrite &amp;lt;- plus_n_O. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite &amp;lt;- plus_n_Sm. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.4. Demostrar que &lt;br /&gt;
      forall n m p : nat, n + (m + p) = (n + m) + p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_assoc : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n m p. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
 -  reflexivity.&lt;br /&gt;
 -simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Se considera la siguiente función que dobla su argumento. &lt;br /&gt;
      Fixpoint double (n:nat) :=&lt;br /&gt;
        match n with&lt;br /&gt;
        | O =&amp;gt; O&lt;br /&gt;
        | S n&amp;#039; =&amp;gt; S (S (double n&amp;#039;))&lt;br /&gt;
        end.&lt;br /&gt;
&lt;br /&gt;
   Demostrar que &lt;br /&gt;
      forall n, double n = n + n. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint double (n:nat) :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; O&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; S (S (double n&amp;#039;))&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Lemma double_plus : forall n, double n = n + n .&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite plus_n_Sm. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Demostrar que&lt;br /&gt;
       forall n : nat, evenb (S n) = negb (evenb n).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem evenb_S : forall n : nat,&lt;br /&gt;
  evenb (S n) = negb (evenb n).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - rewrite IHn&amp;#039;. simpl. rewrite negb_involutive. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Explicar la diferencia entre las tácticas destruct e&lt;br /&gt;
   induction. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* La diferencia es que en la induct siempre tienes una hipótesis, a la&lt;br /&gt;
   que llamas hipótesis de inducción, así como dos únicos casos (el caso&lt;br /&gt;
   del elemento más simple y suponiendo que se cumple para n el de&lt;br /&gt;
   n+1). &lt;br /&gt;
&lt;br /&gt;
   En cambio, en destruct puedes tener mayor número de casos y no &lt;br /&gt;
   suponer una hipótesis.  *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Lemas locales &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de teorema con lema local usando assert. *)&lt;br /&gt;
Theorem mult_0_plus&amp;#039; : forall n m : nat,&lt;br /&gt;
  (0 + n) * m = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  assert (H: 0 + n = n). { reflexivity. }&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Otro ejemplo de teorema con lema local usando assert. &lt;br /&gt;
   Primero, la prueba si assert es *) &lt;br /&gt;
Theorem plus_rearrange_firsttry : forall n m p q : nat,&lt;br /&gt;
  (n + m) + (p + q) = (m + n) + (p + q).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p q.&lt;br /&gt;
  rewrite -&amp;gt; plus_comm.&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* En cambio usando assert *)&lt;br /&gt;
Theorem plus_rearrange : forall n m p q : nat,&lt;br /&gt;
  (n + m) + (p + q) = (m + n) + (p + q).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p q.&lt;br /&gt;
  assert (H: n + m = m + n).&lt;br /&gt;
  { rewrite -&amp;gt; plus_comm. reflexivity. }&lt;br /&gt;
  rewrite -&amp;gt; H. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pruebas formales vs pruebas informales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* &amp;quot;_Informal proofs are algorithms; formal proofs are code_.&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplos de pruebas formales en Coq *)&lt;br /&gt;
Theorem plus_assoc&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [| n&amp;#039; IHn&amp;#039;]. reflexivity.&lt;br /&gt;
  simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem plus_assoc&amp;#039;&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba informal &lt;br /&gt;
&lt;br /&gt;
   Theorem_: For any [n], [m] and [p],&lt;br /&gt;
      n + (m + p) = (n + m) + p.&lt;br /&gt;
&lt;br /&gt;
   Proof: By induction on [n].&lt;br /&gt;
    - First, suppose [n = 0].  We must show&lt;br /&gt;
         0 + (m + p) = (0 + m) + p.&lt;br /&gt;
      This follows directly from the definition of [+].&lt;br /&gt;
&lt;br /&gt;
    - Next, suppose [n = S n&amp;#039;], where&lt;br /&gt;
         n&amp;#039; + (m + p) = (n&amp;#039; + m) + p.&lt;br /&gt;
      We must show&lt;br /&gt;
         (S n&amp;#039;) + (m + p) = ((S n&amp;#039;) + m) + p.&lt;br /&gt;
&lt;br /&gt;
      By the definition of [+], this follows from&lt;br /&gt;
         S (n&amp;#039; + (m + p)) = S ((n&amp;#039; + m) + p),&lt;br /&gt;
      which is immediate from the induction hypothesis.  &lt;br /&gt;
&lt;br /&gt;
    Qed. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Escribir una prueba informal de que la suma es&lt;br /&gt;
   conmutativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Escribir prueba informal de&lt;br /&gt;
      forall n:nat, true = beq_nat n n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios complementarios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar, usando assert pero no induct,&lt;br /&gt;
      forall n m p : nat, n + (m + p) = m + (n + p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_swap : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = m + (n + p).&lt;br /&gt;
Proof. &lt;br /&gt;
  intros n m p. rewrite plus_assoc. rewrite plus_assoc.&lt;br /&gt;
  assert (H : n + m = m+n). {rewrite plus_comm. reflexivity. } &lt;br /&gt;
  rewrite H. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Demostrar que la multiplicación es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem one_id : forall n: nat,&lt;br /&gt;
    n = n*1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [|n IHn&amp;#039;].&lt;br /&gt;
  -reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem one_S : forall n : nat,&lt;br /&gt;
    S n = n+1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;-HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem mult_n_Sm : forall n m : nat, &lt;br /&gt;
    n * (m+1) = n*m+n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - rewrite &amp;lt;- plus_n_O. rewrite &amp;lt;- one_S. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite plus_swap. rewrite &amp;lt;- plus_assoc.&lt;br /&gt;
    rewrite one_S. rewrite &amp;lt;- one_S. rewrite plus_swap.&lt;br /&gt;
    rewrite plus_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem mult_comm : forall m n : nat,&lt;br /&gt;
  m * n = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
 -  rewrite mult_0_r. reflexivity.&lt;br /&gt;
 - simpl. rewrite HIn&amp;#039;. rewrite one_S. rewrite mult_n_Sm. rewrite plus_comm.&lt;br /&gt;
   reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.1. Demostrar que &lt;br /&gt;
      forall n:nat, true = leb n n.  &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem leb_refl : forall n:nat,&lt;br /&gt;
  true = leb n n.&lt;br /&gt;
Proof. intro n. induction n as [| n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - rewrite HIn&amp;#039;. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.2. Demostrar que &lt;br /&gt;
      forall n:nat, beq_nat 0 (S n) = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem zero_nbeq_S : forall n:nat,&lt;br /&gt;
  beq_nat 0 (S n) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.3. Demostrar que &lt;br /&gt;
      forall b : bool, andb b false = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem andb_false_r : forall b : bool,&lt;br /&gt;
  andb b false = false.&lt;br /&gt;
Proof. intros b. destruct b.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. reflexivity. &lt;br /&gt;
Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.4. Demostrar que &lt;br /&gt;
      forall n m p : nat, leb n m = true -&amp;gt; leb (p + n) (p + m) = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_ble_compat_l : forall n m p : nat,&lt;br /&gt;
  leb n m = true -&amp;gt; leb (p + n) (p + m) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p H. rewrite &amp;lt;- H. induction p as [|p&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.5. Demostrar que &lt;br /&gt;
      forall n:nat, beq_nat (S n) 0 = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem S_nbeq_0 : forall n:nat,&lt;br /&gt;
  beq_nat (S n) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.6. Demostrar que &lt;br /&gt;
       forall n:nat, 1 * n = n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_1_l : forall n:nat, 1 * n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. simpl. rewrite plus_n_O. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.7. Demostrar que &lt;br /&gt;
       forall b c : bool, orb (andb b c)&lt;br /&gt;
                              (orb (negb b)&lt;br /&gt;
                                   (negb c))&lt;br /&gt;
                          = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem all3_spec : forall b c : bool,&lt;br /&gt;
    orb&lt;br /&gt;
      (andb b c)&lt;br /&gt;
      (orb (negb b)&lt;br /&gt;
           (negb c))&lt;br /&gt;
    = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [].&lt;br /&gt;
  -  reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.8. Demostrar que &lt;br /&gt;
      forall n m p : nat, (n + m) * p = (n * p) + (m * p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_plus_distr_r : forall n m p : nat,&lt;br /&gt;
  (n + m) * p = (n * p) + (m * p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction p as [| p&amp;#039; HIp&amp;#039;].&lt;br /&gt;
  - rewrite -&amp;gt; mult_0_r. rewrite mult_0_r. rewrite mult_0_r. reflexivity.&lt;br /&gt;
  - rewrite one_S. rewrite mult_comm.&lt;br /&gt;
    rewrite mult_n_Sm. rewrite mult_n_Sm.&lt;br /&gt;
    rewrite plus_assoc. rewrite mult_comm.&lt;br /&gt;
    rewrite mult_n_Sm. rewrite HIp&amp;#039;.&lt;br /&gt;
    rewrite plus_swap. rewrite plus_assoc.&lt;br /&gt;
    rewrite plus_assoc. rewrite &amp;lt;- plus_assoc.&lt;br /&gt;
    rewrite plus_rearrange. rewrite plus_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.9. Demostrar que &lt;br /&gt;
      forall n m p : nat, n * (m * p) = (n * m) * p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_assoc : forall n m p : nat,&lt;br /&gt;
  n * (m * p) = (n * m) * p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. rewrite mult_plus_distr_r. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
       forall n : nat, true = beq_nat n n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem beq_nat_refl : forall n : nat,&lt;br /&gt;
  true = beq_nat n n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [| n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. La táctica replace permite especificar el subtérmino&lt;br /&gt;
   que se desea reescribir y su sustituto: [replace (t) with (u)]&lt;br /&gt;
   sustituye todas las copias de la expresión t en el objetivo por la&lt;br /&gt;
   expresión u y añade la ecuación (t = u) como un nuevo subojetivo. &lt;br /&gt;
 &lt;br /&gt;
   El uso de la táctica replace es especialmente útil cuando la táctica &lt;br /&gt;
   rewrite actúa sobre una parte del objetivo que no es la que se desea. &lt;br /&gt;
&lt;br /&gt;
   Demostrar, usando la táctica replace y sin usar &lt;br /&gt;
   [assert (n + m = m + n)], que&lt;br /&gt;
      forall n m p : nat, n + (m + p) = m + (n + p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_swap&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = m + (n + p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. rewrite plus_assoc. rewrite plus_assoc.&lt;br /&gt;
  replace (n+m) with (m+n). &lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - rewrite plus_comm. reflexivity.&lt;br /&gt;
Qed. &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/SLC2018/index.php?title=Tema_1&amp;diff=80</id>
		<title>Tema 1</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_1&amp;diff=80"/>
		<updated>2018-03-25T08:33:47Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: Protegió «Tema 1» ([edit=sysop] (indefinido) [move=sysop] (indefinido))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T1: Programación funcional en Coq *)&lt;br /&gt;
&lt;br /&gt;
Definition admit {T: Type} : T.  Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Datos y funciones &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Tipos enumerados  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo day cuyos constructores sean los días de&lt;br /&gt;
   la semana.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive day : Type :=&lt;br /&gt;
  | monday    : day&lt;br /&gt;
  | tuesday   : day&lt;br /&gt;
  | wednesday : day&lt;br /&gt;
  | thursday  : day&lt;br /&gt;
  | friday    : day&lt;br /&gt;
  | saturday  : day&lt;br /&gt;
  | sunday    : day.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      next_weekday :: day -&amp;gt; day &lt;br /&gt;
   tal que (next_weekday d) es el día laboral siguiente a d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition next_weekday (d:day) : day :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | monday    =&amp;gt; tuesday&lt;br /&gt;
  | tuesday   =&amp;gt; wednesday&lt;br /&gt;
  | wednesday =&amp;gt; thursday&lt;br /&gt;
  | thursday  =&amp;gt; friday&lt;br /&gt;
  | friday    =&amp;gt; monday&lt;br /&gt;
  | saturday  =&amp;gt; monday&lt;br /&gt;
  | sunday    =&amp;gt; monday&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el valor de las siguientes expresiones &lt;br /&gt;
      + (next_weekday friday)&lt;br /&gt;
      + (next_weekday (next_weekday saturday))&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (next_weekday friday).&lt;br /&gt;
(* ==&amp;gt; monday : day *)&lt;br /&gt;
&lt;br /&gt;
Compute (next_weekday (next_weekday saturday)).&lt;br /&gt;
(* ==&amp;gt; tuesday : day *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
      (next_weekday (next_weekday saturday)) = tuesday&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_next_weekday:&lt;br /&gt;
  (next_weekday (next_weekday saturday)) = tuesday.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Booleanos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo bool cuyos constructores son true y false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive bool : Type :=&lt;br /&gt;
  | true  : bool&lt;br /&gt;
  | false : bool.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      negb :: bool -&amp;gt; bool&lt;br /&gt;
   tal que (negb b) es la negación de b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition negb (b:bool) : bool :=&lt;br /&gt;
  match b with&lt;br /&gt;
  | true  =&amp;gt; false&lt;br /&gt;
  | false =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      andb :: bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (andb b1 b2) es la conjunción de b1 y b2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition andb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true =&amp;gt; b2&lt;br /&gt;
  | false =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      orb :: bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (orb b1 b2) es la disyunción de b1 y b2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition orb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true  =&amp;gt; true&lt;br /&gt;
  | false =&amp;gt; b2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar las siguientes propiedades&lt;br /&gt;
      (orb true  false) = true.&lt;br /&gt;
      (orb false false) = false.&lt;br /&gt;
      (orb false true)  = true.&lt;br /&gt;
      (orb true  true)  = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_orb1: (orb true  false) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb2: (orb false false) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb3: (orb false true)  = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb4: (orb true  true)  = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir los operadores (&amp;amp;&amp;amp;) y (||) como abreviaturas de las&lt;br /&gt;
   funciones andb y orb.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x &amp;amp;&amp;amp; y&amp;quot; := (andb x y).&lt;br /&gt;
Notation &amp;quot;x || y&amp;quot; := (orb x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      false || false || true = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_orb5: false || false || true = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Definir la función &lt;br /&gt;
      nandb :: bool -&amp;gt; bool -&amp;gt; bool &lt;br /&gt;
   tal que (nanb x y) se verifica si x e y no son verdaderos.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades de nand&lt;br /&gt;
      (nandb true  false) = true.&lt;br /&gt;
      (nandb false false) = true.&lt;br /&gt;
      (nandb false true)  = true.&lt;br /&gt;
      (nandb true  true)  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition nandb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with &lt;br /&gt;
  | true  =&amp;gt; negb b2&lt;br /&gt;
  | false =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_nandb1: (nandb true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb2: (nandb false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb3: (nandb false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb4: (nandb true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb1 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true =&amp;gt; negb b2&lt;br /&gt;
  | _    =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb11: (nandb1 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb12: (nandb1 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb13: (nandb1 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb14: (nandb1 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb2 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1, b2 with&lt;br /&gt;
  | true, true =&amp;gt; false&lt;br /&gt;
  | _, _       =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb21: (nandb2 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb22: (nandb2 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb23: (nandb2 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb24: (nandb2 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb3 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  if b1 then negb b2 else true.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb31: (nandb3 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb32: (nandb3 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb33: (nandb3 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb34: (nandb3 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb4 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  negb (b1 &amp;amp;&amp;amp; b2).&lt;br /&gt;
&lt;br /&gt;
Example test_nandb41: (nandb4 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb42: (nandb4 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb43: (nandb4 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb44: (nandb4 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Definir la función&lt;br /&gt;
      andb3 :: bool -&amp;gt; bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (andb3 x y z) se verifica si x, y y z son verdaderos.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades de andb3&lt;br /&gt;
      (andb3 true  true  true)  = true.&lt;br /&gt;
      (andb3 false true  true)  = false.&lt;br /&gt;
      (andb3 true  false true)  = false.&lt;br /&gt;
      (andb3 true  true  false) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition andb3 (b1:bool) (b2:bool) (b3:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
   | true  =&amp;gt; andb b2 b3&lt;br /&gt;
   | false =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_andb31: (andb3 true true true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb32: (andb3 false true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb33: (andb3 true false true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb34: (andb3 true true false) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Notation &amp;quot;x &amp;amp;&amp;amp; y&amp;quot; := (andb x y).&lt;br /&gt;
&lt;br /&gt;
Definition andb32 (b1:bool) (b2:bool) (b3:bool) : bool :=&lt;br /&gt;
  b1 &amp;amp;&amp;amp; b2 &amp;amp;&amp;amp; b3.&lt;br /&gt;
&lt;br /&gt;
Example test_andb321: (andb32 true true true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb322: (andb32 false true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb323: (andb32 true false true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb324: (andb32 true true false) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Tipos de las funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de las siguientes expresiones&lt;br /&gt;
      + true&lt;br /&gt;
      + (negb true)&lt;br /&gt;
      + negb&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check true.&lt;br /&gt;
(* ===&amp;gt; true : bool *)&lt;br /&gt;
&lt;br /&gt;
Check (negb true).&lt;br /&gt;
(* ===&amp;gt; negb true : bool *)&lt;br /&gt;
&lt;br /&gt;
Check negb.&lt;br /&gt;
(* ===&amp;gt; negb : bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Tipos compuestos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo rgb cuyos constructores son red, green y&lt;br /&gt;
   blue. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive rgb : Type :=&lt;br /&gt;
  | red   : rgb&lt;br /&gt;
  | green : rgb&lt;br /&gt;
  | blue  : rgb.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo color cuyos constructores son black, white y&lt;br /&gt;
   primary, donde primary es una función de rgb en color.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive color : Type :=&lt;br /&gt;
  | black   : color&lt;br /&gt;
  | white   : color&lt;br /&gt;
  | primary : rgb -&amp;gt; color.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      monochrome :: color -&amp;gt; bool&lt;br /&gt;
   tal que (monochrome c) se verifica si c es monocromático.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition monochrome (c : color) : bool :=&lt;br /&gt;
  match c with&lt;br /&gt;
  | black     =&amp;gt; true&lt;br /&gt;
  | white     =&amp;gt; true&lt;br /&gt;
  | primary p =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      isred :: color -&amp;gt; bool&lt;br /&gt;
   tal que (isred c) se verifica si c es rojo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition isred (c : color) : bool :=&lt;br /&gt;
  match c with&lt;br /&gt;
  | black       =&amp;gt; false&lt;br /&gt;
  | white       =&amp;gt; false&lt;br /&gt;
  | primary red =&amp;gt; true&lt;br /&gt;
  | primary _   =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Módulos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Iniciar el módulo NatPlayground.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatPlayground.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Números naturales  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo nat de los números naturales con los&lt;br /&gt;
   constructores 0 (para el 0) y S (para el siguiente).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Inductive nat : Type :=&lt;br /&gt;
  | O : nat&lt;br /&gt;
  | S : nat -&amp;gt; nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      pred :: nat -&amp;gt; nat&lt;br /&gt;
   tal que (pred n) es el predecesor de n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Definition pred (n : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; O&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Finaliz el módulo NatPlayground.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatPlayground.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo y valor de la expresión (S (S (S (S O)))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (S (S (S (S O)))).&lt;br /&gt;
  (* ===&amp;gt; 4 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      minustwo :: nat -&amp;gt; nat&lt;br /&gt;
   tal que (minustwo n) es n-2. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition minustwo (n : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O        =&amp;gt; O&lt;br /&gt;
    | S O      =&amp;gt; O&lt;br /&gt;
    | S (S n&amp;#039;) =&amp;gt; n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión (minustwo 4).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (minustwo 4).&lt;br /&gt;
  (* ===&amp;gt; 2 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular et tipo de las funcionse S, pred y minustwo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check S.&lt;br /&gt;
Check pred.&lt;br /&gt;
Check minustwo.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      evenb :: nat -&amp;gt; bool&lt;br /&gt;
   tal que (evenb n) se verifica si n es par.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint evenb (n:nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O        =&amp;gt; true&lt;br /&gt;
  | S O      =&amp;gt; false&lt;br /&gt;
  | S (S n&amp;#039;) =&amp;gt; evenb n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      oddb :: nat -&amp;gt; bool&lt;br /&gt;
   tal que (oddb n) se verifica si n es impar.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition oddb (n:nat) : bool   :=   negb (evenb n).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      + oddb 1 = true.&lt;br /&gt;
      + oddb 4 = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_oddb1: oddb 1 = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_oddb2: oddb 4 = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Iniciar el módulo NatPlayground2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatPlayground2.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus 3 2 = 5&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint plus (n : nat) (m : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; m&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; S (plus n&amp;#039; m)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Compute (plus 3 2).&lt;br /&gt;
(* ===&amp;gt; 5: nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      mult :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult 3 2 = 6&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint mult (n m : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; O&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; plus m (mult n&amp;#039; m)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_mult1: (mult 2 3) = 6.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      minus :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (minus n m) es la diferencia de n y m. Por ejemplo,&lt;br /&gt;
      mult 3 2 = 1&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint minus (n m:nat) : nat :=&lt;br /&gt;
  match (n, m) with&lt;br /&gt;
  | (O   , _)    =&amp;gt; O&lt;br /&gt;
  | (S _ , O)    =&amp;gt; n&lt;br /&gt;
  | (S n&amp;#039;, S m&amp;#039;) =&amp;gt; minus n&amp;#039; m&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Cerrar el módulo NatPlayground2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatPlayground2.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      exp : nat -&amp;gt;  nat -&amp;gt; nat&lt;br /&gt;
   tal que (exp x n) es la potencia n-ésima de x. Por ejemplo,&lt;br /&gt;
      exp 2 3 = 8&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint exp (base power : nat) : nat :=&lt;br /&gt;
  match power with&lt;br /&gt;
    | O   =&amp;gt; S O&lt;br /&gt;
    | S p =&amp;gt; mult base (exp base p)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Compute (exp 2 3).&lt;br /&gt;
(* ===&amp;gt; 8 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      factorial :: nat -&amp;gt; nat1&lt;br /&gt;
   tal que (factorial n) es el factorial de n. &lt;br /&gt;
&lt;br /&gt;
      (factorial 3) = 6.&lt;br /&gt;
      (factorial 5) = (mult 10 12).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5, angruicam1 *)&lt;br /&gt;
Fixpoint factorial (n:nat) : nat := &lt;br /&gt;
  match n with&lt;br /&gt;
  | O    =&amp;gt; 1&lt;br /&gt;
  | S n&amp;#039; =&amp;gt;  S n&amp;#039; * factorial n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_factorial1: (factorial 3) = 6.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_factorial2: (factorial 5) = (mult 10 12).&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir los operadores +, - y * como abreviaturas de  las&lt;br /&gt;
   funciones plus, minus y mult.  &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x + y&amp;quot; := (plus x y)&lt;br /&gt;
                       (at level 50, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
Notation &amp;quot;x - y&amp;quot; := (minus x y)&lt;br /&gt;
                       (at level 50, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
Notation &amp;quot;x * y&amp;quot; := (mult x y)&lt;br /&gt;
                       (at level 40, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_nat : nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (beq_nat n m) se verifica si n y me son iguales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_nat (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; match m with&lt;br /&gt;
         | O    =&amp;gt; true&lt;br /&gt;
         | S m&amp;#039; =&amp;gt; false&lt;br /&gt;
         end&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; match m with&lt;br /&gt;
            | O    =&amp;gt; false&lt;br /&gt;
            | S m&amp;#039; =&amp;gt; beq_nat n&amp;#039; m&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      leb : nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (leb n m) se verifica si n es menor o igual que m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint leb (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O    =&amp;gt; true&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; match m with&lt;br /&gt;
            | O    =&amp;gt; false&lt;br /&gt;
            | S m&amp;#039; =&amp;gt; leb n&amp;#039; m&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar las siguientes propiedades&lt;br /&gt;
      + (leb 2 2) = true.&lt;br /&gt;
      + (leb 2 4) = true.&lt;br /&gt;
      + (leb 4 2) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_leb1: (leb 2 2) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_leb2: (leb 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_leb3: (leb 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      blt_nat :: nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (blt n m) se verifica si n es menor que m.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades&lt;br /&gt;
      (blt_nat 2 2) = false.&lt;br /&gt;
      (blt_nat 2 4) = true.&lt;br /&gt;
      (blt_nat 4 2) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition blt_nat (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; true&lt;br /&gt;
  | S n&amp;#039; =&amp;gt;&lt;br /&gt;
      match m with&lt;br /&gt;
      | O    =&amp;gt; false&lt;br /&gt;
      | S m&amp;#039; =&amp;gt; leb (S n&amp;#039;)  m&amp;#039;&lt;br /&gt;
      end&lt;br /&gt;
  end.                                   &lt;br /&gt;
&lt;br /&gt;
Example prop_blt_nat1: (blt_nat 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_blt_nat2: (blt_nat 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_blt_nat3: (blt_nat 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition blt_nat2 (n m : nat) : bool :=&lt;br /&gt;
  negb (beq_nat (m-n) 0).&lt;br /&gt;
&lt;br /&gt;
Example test_blt_nat21: (blt_nat2 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_blt_nat22: (blt_nat2 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_blt_nat23: (blt_nat2 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por simplificación &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que el 0 es el elemento neutro por la izquierda de&lt;br /&gt;
   la suma de los números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración *)&lt;br /&gt;
Theorem plus_O_n : forall n : nat, 0 + n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración *)&lt;br /&gt;
Theorem plus_O_n&amp;#039; : forall n : nat, 0 + n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la suma de 1 y n es el siguiente de n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_1_l : forall n:nat, 1 + n = S n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que el producto de 0 por n es 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem mult_0_l : forall n:nat, 0 * n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por reescritura &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que si n = m, entonces n + n = m + m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Theorem plus_id_example : forall n m:nat,&lt;br /&gt;
  n = m -&amp;gt;&lt;br /&gt;
  n + n = m + m.&lt;br /&gt;
&lt;br /&gt;
Proof.&lt;br /&gt;
  (* move both quantifiers into the context: *)&lt;br /&gt;
  intros n m.&lt;br /&gt;
  (* move the hypothesis into the context: *)&lt;br /&gt;
  intros H.&lt;br /&gt;
  (* rewrite the goal using the hypothesis: *)&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Demostrar que si n = m y m = o, entonces n + m = m + o.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_id_exercise: forall n m o : nat,&lt;br /&gt;
  n = m -&amp;gt; m = o -&amp;gt; n + m = m + o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  intros o Ho.&lt;br /&gt;
  rewrite -&amp;gt; Ho.&lt;br /&gt;
  intros H.&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem plus_id_exercise2 : forall n m o : nat,&lt;br /&gt;
  n = m -&amp;gt; m = o -&amp;gt; n + m = m + o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o H1 H2.&lt;br /&gt;
  rewrite -&amp;gt; H1.&lt;br /&gt;
  rewrite -&amp;gt; H2.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que (0 + n) * m = n * m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem mult_0_plus : forall n m : nat,&lt;br /&gt;
  (0 + n) * m = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  rewrite -&amp;gt; plus_O_n.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar que si m = S n, entonces m * (1 + n) = m * m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_S_1 : forall n m : nat,&lt;br /&gt;
  m = S n -&amp;gt;&lt;br /&gt;
  m * (1 + n) = m * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  intros H.&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem mult_S_12 : forall n m : nat,&lt;br /&gt;
  m = S n -&amp;gt;&lt;br /&gt;
  m * (1 + n) = m * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  rewrite H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por análisis de casos &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que n + 1 es distinto de 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1º intento *)&lt;br /&gt;
Theorem plus_1_neq_0_firsttry : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  simpl.  (* does nothing! *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* 2º intento *)&lt;br /&gt;
Theorem plus_1_neq_0 : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n as [| n&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la negación es involutiva; es decir, la&lt;br /&gt;
   negación de la negación de b es b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem negb_involutive : forall b : bool,&lt;br /&gt;
  negb (negb b) = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b. destruct b.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración *)&lt;br /&gt;
Theorem andb_commutative : forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración *)&lt;br /&gt;
Theorem andb_commutative&amp;#039; : forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  { destruct c.&lt;br /&gt;
    { reflexivity. }&lt;br /&gt;
    { reflexivity. } }&lt;br /&gt;
  { destruct c.&lt;br /&gt;
    { reflexivity. }&lt;br /&gt;
    { reflexivity. } }&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem andb3_exchange :&lt;br /&gt;
  forall b c d, andb (andb b c) d = andb (andb b d) c.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c d. destruct b.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que n + 1 es distinto de 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_1_neq_0&amp;#039; : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [|n].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem andb_commutative&amp;#039;&amp;#039; :&lt;br /&gt;
  forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que si andb b c = true, entonces c = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem andb_true_elim2 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  - intros H. rewrite &amp;lt;-H. reflexivity.&lt;br /&gt;
  - intros H. rewrite &amp;lt;-H. destruct false.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + destruct c. rewrite &amp;lt;-H. reflexivity. reflexivity. &lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem andb_true_elim22 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [] [].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* jorcatote *)&lt;br /&gt;
Theorem andb_true_elim23 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct c.&lt;br /&gt;
    - reflexivity.   &lt;br /&gt;
    - destruct b.&lt;br /&gt;
      + simpl. intros h. rewrite h. reflexivity.&lt;br /&gt;
      + simpl. intros h. rewrite h. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Dmostrar que 0 es distinto de n + 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem zero_nbeq_plus_1: forall n : nat,&lt;br /&gt;
  beq_nat 0 (n + 1) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem zero_nbeq_plus_12 : forall n : nat,&lt;br /&gt;
  beq_nat 0 (n + 1) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [| n&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios complementarios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Demostrar que&lt;br /&gt;
      forall (f : bool -&amp;gt; bool),&lt;br /&gt;
        (forall (x : bool), f x = x) -&amp;gt; &lt;br /&gt;
        forall (b : bool), f (f b) = b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1, alerodrod5 *)&lt;br /&gt;
Theorem identity_fn_applied_twice :&lt;br /&gt;
  forall (f : bool -&amp;gt; bool),&lt;br /&gt;
  (forall (x : bool), f x = x) -&amp;gt;&lt;br /&gt;
  forall (b : bool), f (f b) = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros f x b.&lt;br /&gt;
  rewrite x.&lt;br /&gt;
  rewrite x.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
      forall (b c : bool),&lt;br /&gt;
        (andb b c = orb b c) -&amp;gt; b = c.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 alerodrod5 *)&lt;br /&gt;
Theorem andb_eq_orb :&lt;br /&gt;
  forall (b c : bool),&lt;br /&gt;
  (andb b c = orb b c) -&amp;gt;&lt;br /&gt;
  b = c.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] c.&lt;br /&gt;
  - simpl. intros H. rewrite H. reflexivity.&lt;br /&gt;
  - simpl. intros H. rewrite H. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. En este ejercicio se considera la siguiente&lt;br /&gt;
   representación de los números naturales&lt;br /&gt;
      Inductive nat2 : Type :=&lt;br /&gt;
        | C  : nat2&lt;br /&gt;
        | D  : nat2 -&amp;gt; nat2&lt;br /&gt;
        | SD : nat2 -&amp;gt; nat2.&lt;br /&gt;
   donde C representa el cero, D el doble y SD el siguiente del doble.&lt;br /&gt;
&lt;br /&gt;
   Definir la función&lt;br /&gt;
      nat2Anat :: nat2 -&amp;gt; nat&lt;br /&gt;
   tal que (nat2Anat x) es el número natural representado por x. &lt;br /&gt;
&lt;br /&gt;
   Demostrar que &lt;br /&gt;
      nat2Anat (SD (SD C))     = 3&lt;br /&gt;
      nat2Anat (D (SD (SD C))) = 6.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1, alerodrod5 *)&lt;br /&gt;
Inductive nat2 : Type :=&lt;br /&gt;
  | C  : nat2&lt;br /&gt;
  | D  : nat2 -&amp;gt; nat2&lt;br /&gt;
  | SD : nat2 -&amp;gt; nat2.&lt;br /&gt;
 &lt;br /&gt;
Fixpoint nat2Anat (x:nat2) : nat :=&lt;br /&gt;
  match x with&lt;br /&gt;
  | C =&amp;gt; O&lt;br /&gt;
  | D n =&amp;gt; 2*nat2Anat n&lt;br /&gt;
  | SD n =&amp;gt; (2*nat2Anat n)+1&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example prop_nat2Anat1: (nat2Anat (SD (SD C))) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example prop_nat2Anat2: (nat2Anat (D (SD (SD C)))) = 6.&lt;br /&gt;
Proof. reflexivity. Qed.&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/SLC2018/index.php?title=Seminario_de_L%C3%B3gica_Computacional_(2018):Seminario_de_L%C3%B3gica_Computacional_(2018)&amp;diff=79</id>
		<title>Seminario de Lógica Computacional (2018):Seminario de Lógica Computacional (2018)</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Seminario_de_L%C3%B3gica_Computacional_(2018):Seminario_de_L%C3%B3gica_Computacional_(2018)&amp;diff=79"/>
		<updated>2018-03-24T10:52:28Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Material para el seminario */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material para el seminario ==&lt;br /&gt;
* [[Temas]]: Teorías de los temas (incluyendo los ejercicios).&lt;br /&gt;
* [[Documentación]]: Lecturas recomendadas.&lt;br /&gt;
* [[Sistemas]]: Sistemas utilizados.&lt;br /&gt;
* [http://www.glc.us.es/~jalonso/vestigium/tag/slc2018 Diario]: Descripción diaria de las sesiones.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Seminario_de_L%C3%B3gica_Computacional_(2018):Seminario_de_L%C3%B3gica_Computacional_(2018)&amp;diff=78</id>
		<title>Seminario de Lógica Computacional (2018):Seminario de Lógica Computacional (2018)</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Seminario_de_L%C3%B3gica_Computacional_(2018):Seminario_de_L%C3%B3gica_Computacional_(2018)&amp;diff=78"/>
		<updated>2018-03-24T10:52:05Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material para el seminario ==&lt;br /&gt;
* [[Temas]]: Teorías de los temas.&lt;br /&gt;
* [[Documentación]]: Lecturas recomendadas.&lt;br /&gt;
* [[Sistemas]]: Sistemas utilizados.&lt;br /&gt;
* [http://www.glc.us.es/~jalonso/vestigium/tag/slc2018 Diario]: Descripción diaria de las sesiones.&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=MediaWiki:Sidebar&amp;diff=77</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=MediaWiki:Sidebar&amp;diff=77"/>
		<updated>2018-03-24T10:51:53Z</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;
** Documentación|Documentación&lt;br /&gt;
** Sistemas|Sistemas&lt;br /&gt;
** http://www.glc.us.es/~jalonso/vestigium/tag/ra2017|Diario&lt;br /&gt;
** https://twitter.com/search?f=tweets&amp;amp;q=%23SLC2018%20from:Jose_A_Alonso|Twitter&lt;br /&gt;
** recentchanges-url|recentchanges&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/SLC2018/index.php?title=Temas&amp;diff=76</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=76"/>
		<updated>2018-03-24T10:51:20Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: Programación funcional en Coq&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_2&amp;diff=75</id>
		<title>Tema 2</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_2&amp;diff=75"/>
		<updated>2018-03-24T10:50:31Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T2: Demostraciones por inducción en Coq *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de importación de teorías *)&lt;br /&gt;
Require Export T1_PF_en_Coq.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pruebas por inducción &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de demostración que no puede ser realizada por el método &lt;br /&gt;
   simple  *) &lt;br /&gt;
Theorem plus_n_O_firsttry : forall n:nat,&lt;br /&gt;
  n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  simpl. (* ¡¡¡No hace nada!!! *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem plus_n_O_secondtry : forall n:nat,&lt;br /&gt;
  n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n as [| n&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    reflexivity. (* Hasta aquí todo bien ... *)&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl.       (* ... pero otra vez no hacemos nada *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba por inducción de n = n + 0. *)&lt;br /&gt;
Theorem plus_n_O : forall n:nat, n = n + 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)    reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *) simpl. rewrite &amp;lt;- IHn&amp;#039;. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba por inducción de (minus n n = 0). *)&lt;br /&gt;
Theorem minus_diag : forall n,&lt;br /&gt;
  minus n n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    simpl. reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.1. Demostrar que &lt;br /&gt;
      forall n:nat, n * 0 = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_0_r : forall n:nat,&lt;br /&gt;
  n * 0 = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.2. Demostrar que &lt;br /&gt;
      forall n m : nat, S (n + m) = n + (S m).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_n_Sm : forall n m : nat,&lt;br /&gt;
  S (n + m) = n + (S m).&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.3. Demostrar que &lt;br /&gt;
      forall n m : nat, n + m = m + n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_comm : forall n m : nat,&lt;br /&gt;
  n + m = m + n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros  n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. rewrite &amp;lt;- plus_n_O. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite &amp;lt;- plus_n_Sm. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1.4. Demostrar que &lt;br /&gt;
      forall n m p : nat, n + (m + p) = (n + m) + p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_assoc : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n m p. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
 -  reflexivity.&lt;br /&gt;
 -simpl. rewrite IHn&amp;#039;. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Se considera la siguiente función que dobla su argumento. &lt;br /&gt;
      Fixpoint double (n:nat) :=&lt;br /&gt;
        match n with&lt;br /&gt;
        | O =&amp;gt; O&lt;br /&gt;
        | S n&amp;#039; =&amp;gt; S (S (double n&amp;#039;))&lt;br /&gt;
        end.&lt;br /&gt;
&lt;br /&gt;
   Demostrar que &lt;br /&gt;
      forall n, double n = n + n. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint double (n:nat) :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; O&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; S (S (double n&amp;#039;))&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Lemma double_plus : forall n, double n = n + n .&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite plus_n_Sm. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Demostrar que&lt;br /&gt;
       forall n : nat, evenb (S n) = negb (evenb n).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem evenb_S : forall n : nat,&lt;br /&gt;
  evenb (S n) = negb (evenb n).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - rewrite IHn&amp;#039;. simpl. rewrite negb_involutive. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Explicar la diferencia entre las tácticas destruct e&lt;br /&gt;
   induction. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* La diferencia es que en la induct siempre tienes una hipótesis, a la&lt;br /&gt;
   que llamas hipótesis de inducción, así como dos únicos casos (el caso&lt;br /&gt;
   del elemento más simple y suponiendo que se cumple para n el de&lt;br /&gt;
   n+1). &lt;br /&gt;
&lt;br /&gt;
   En cambio, en destruct puedes tener mayor número de casos y no &lt;br /&gt;
   suponer una hipótesis.  *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Lemas locales &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo de teorema con lema local usando assert. *)&lt;br /&gt;
Theorem mult_0_plus&amp;#039; : forall n m : nat,&lt;br /&gt;
  (0 + n) * m = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  assert (H: 0 + n = n). { reflexivity. }&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Otro ejemplo de teorema con lema local usando assert. &lt;br /&gt;
   Primero, la prueba si assert es *) &lt;br /&gt;
Theorem plus_rearrange_firsttry : forall n m p q : nat,&lt;br /&gt;
  (n + m) + (p + q) = (m + n) + (p + q).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p q.&lt;br /&gt;
  rewrite -&amp;gt; plus_comm.&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* En cambio usando assert *)&lt;br /&gt;
Theorem plus_rearrange : forall n m p q : nat,&lt;br /&gt;
  (n + m) + (p + q) = (m + n) + (p + q).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p q.&lt;br /&gt;
  assert (H: n + m = m + n).&lt;br /&gt;
  { rewrite -&amp;gt; plus_comm. reflexivity. }&lt;br /&gt;
  rewrite -&amp;gt; H. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pruebas formales vs pruebas informales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* &amp;quot;_Informal proofs are algorithms; formal proofs are code_.&amp;quot; *)&lt;br /&gt;
&lt;br /&gt;
(* Ejemplos de pruebas formales en Coq *)&lt;br /&gt;
Theorem plus_assoc&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [| n&amp;#039; IHn&amp;#039;]. reflexivity.&lt;br /&gt;
  simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem plus_assoc&amp;#039;&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = (n + m) + p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* n = 0 *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* n = S n&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ejemplo prueba informal &lt;br /&gt;
&lt;br /&gt;
   Theorem_: For any [n], [m] and [p],&lt;br /&gt;
      n + (m + p) = (n + m) + p.&lt;br /&gt;
&lt;br /&gt;
   Proof: By induction on [n].&lt;br /&gt;
    - First, suppose [n = 0].  We must show&lt;br /&gt;
         0 + (m + p) = (0 + m) + p.&lt;br /&gt;
      This follows directly from the definition of [+].&lt;br /&gt;
&lt;br /&gt;
    - Next, suppose [n = S n&amp;#039;], where&lt;br /&gt;
         n&amp;#039; + (m + p) = (n&amp;#039; + m) + p.&lt;br /&gt;
      We must show&lt;br /&gt;
         (S n&amp;#039;) + (m + p) = ((S n&amp;#039;) + m) + p.&lt;br /&gt;
&lt;br /&gt;
      By the definition of [+], this follows from&lt;br /&gt;
         S (n&amp;#039; + (m + p)) = S ((n&amp;#039; + m) + p),&lt;br /&gt;
      which is immediate from the induction hypothesis.  &lt;br /&gt;
&lt;br /&gt;
    Qed. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Escribir una prueba informal de que la suma es&lt;br /&gt;
   conmutativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Escribir prueba informal de&lt;br /&gt;
      forall n:nat, true = beq_nat n n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios complementarios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar, usando assert pero no induct,&lt;br /&gt;
      forall n m p : nat, n + (m + p) = m + (n + p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_swap : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = m + (n + p).&lt;br /&gt;
Proof. &lt;br /&gt;
  intros n m p. rewrite plus_assoc. rewrite plus_assoc.&lt;br /&gt;
  assert (H : n + m = m+n). {rewrite plus_comm. reflexivity. } &lt;br /&gt;
  rewrite H. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Demostrar que la multiplicación es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem one_id : forall n: nat,&lt;br /&gt;
    n = n*1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [|n IHn&amp;#039;].&lt;br /&gt;
  -reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- IHn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem one_S : forall n : nat,&lt;br /&gt;
    S n = n+1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;-HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem mult_n_Sm : forall n m : nat, &lt;br /&gt;
    n * (m+1) = n*m+n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m. induction n as [|n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - rewrite &amp;lt;- plus_n_O. rewrite &amp;lt;- one_S. reflexivity.&lt;br /&gt;
  - simpl. rewrite IHn&amp;#039;. rewrite plus_swap. rewrite &amp;lt;- plus_assoc.&lt;br /&gt;
    rewrite one_S. rewrite &amp;lt;- one_S. rewrite plus_swap.&lt;br /&gt;
    rewrite plus_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
Theorem mult_comm : forall m n : nat,&lt;br /&gt;
  m * n = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
 -  rewrite mult_0_r. reflexivity.&lt;br /&gt;
 - simpl. rewrite HIn&amp;#039;. rewrite one_S. rewrite mult_n_Sm. rewrite plus_comm.&lt;br /&gt;
   reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.1. Demostrar que &lt;br /&gt;
      forall n:nat, true = leb n n.  &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem leb_refl : forall n:nat,&lt;br /&gt;
  true = leb n n.&lt;br /&gt;
Proof. intro n. induction n as [| n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - rewrite HIn&amp;#039;. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.2. Demostrar que &lt;br /&gt;
      forall n:nat, beq_nat 0 (S n) = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem zero_nbeq_S : forall n:nat,&lt;br /&gt;
  beq_nat 0 (S n) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
 intros n. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.3. Demostrar que &lt;br /&gt;
      forall b : bool, andb b false = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem andb_false_r : forall b : bool,&lt;br /&gt;
  andb b false = false.&lt;br /&gt;
Proof. intros b. destruct b.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. reflexivity. &lt;br /&gt;
Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.4. Demostrar que &lt;br /&gt;
      forall n m p : nat, leb n m = true -&amp;gt; leb (p + n) (p + m) = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_ble_compat_l : forall n m p : nat,&lt;br /&gt;
  leb n m = true -&amp;gt; leb (p + n) (p + m) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p H. rewrite &amp;lt;- H. induction p as [|p&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.5. Demostrar que &lt;br /&gt;
      forall n:nat, beq_nat (S n) 0 = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem S_nbeq_0 : forall n:nat,&lt;br /&gt;
  beq_nat (S n) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.6. Demostrar que &lt;br /&gt;
       forall n:nat, 1 * n = n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_1_l : forall n:nat, 1 * n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. simpl. rewrite plus_n_O. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.7. Demostrar que &lt;br /&gt;
       forall b c : bool, orb (andb b c)&lt;br /&gt;
                              (orb (negb b)&lt;br /&gt;
                                   (negb c))&lt;br /&gt;
                          = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem all3_spec : forall b c : bool,&lt;br /&gt;
    orb&lt;br /&gt;
      (andb b c)&lt;br /&gt;
      (orb (negb b)&lt;br /&gt;
           (negb c))&lt;br /&gt;
    = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [].&lt;br /&gt;
  -  reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.8. Demostrar que &lt;br /&gt;
      forall n m p : nat, (n + m) * p = (n * p) + (m * p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_plus_distr_r : forall n m p : nat,&lt;br /&gt;
  (n + m) * p = (n * p) + (m * p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction p as [| p&amp;#039; HIp&amp;#039;].&lt;br /&gt;
  - rewrite -&amp;gt; mult_0_r. rewrite mult_0_r. rewrite mult_0_r. reflexivity.&lt;br /&gt;
  - rewrite one_S. rewrite mult_comm.&lt;br /&gt;
    rewrite mult_n_Sm. rewrite mult_n_Sm.&lt;br /&gt;
    rewrite plus_assoc. rewrite mult_comm.&lt;br /&gt;
    rewrite mult_n_Sm. rewrite HIp&amp;#039;.&lt;br /&gt;
    rewrite plus_swap. rewrite plus_assoc.&lt;br /&gt;
    rewrite plus_assoc. rewrite &amp;lt;- plus_assoc.&lt;br /&gt;
    rewrite plus_rearrange. rewrite plus_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9.9. Demostrar que &lt;br /&gt;
      forall n m p : nat, n * (m * p) = (n * m) * p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_assoc : forall n m p : nat,&lt;br /&gt;
  n * (m * p) = (n * m) * p.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. induction n as [|n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. rewrite mult_plus_distr_r. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
       forall n : nat, true = beq_nat n n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem beq_nat_refl : forall n : nat,&lt;br /&gt;
  true = beq_nat n n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro n. induction n as [| n&amp;#039; HIn&amp;#039;].&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
  - simpl. rewrite HIn&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. La táctica replace permite especificar el subtérmino&lt;br /&gt;
   que se desea reescribir y su sustituto: [replace (t) with (u)]&lt;br /&gt;
   sustituye todas las copias de la expresión t en el objetivo por la&lt;br /&gt;
   expresión u y añade la ecuación (t = u) como un nuevo subojetivo. &lt;br /&gt;
 &lt;br /&gt;
   El uso de la táctica replace es especialmente útil cuando la táctica &lt;br /&gt;
   rewrite actúa sobre una parte del objetivo que no es la que se desea. &lt;br /&gt;
&lt;br /&gt;
   Demostrar, usando la táctica replace y sin usar &lt;br /&gt;
   [assert (n + m = m + n)], que&lt;br /&gt;
      forall n m p : nat, n + (m + p) = m + (n + p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_swap&amp;#039; : forall n m p : nat,&lt;br /&gt;
  n + (m + p) = m + (n + p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m p. rewrite plus_assoc. rewrite plus_assoc.&lt;br /&gt;
  replace (n+m) with (m+n). &lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - rewrite plus_comm. reflexivity.&lt;br /&gt;
Qed. &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/SLC2018/index.php?title=Temas&amp;diff=74</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=74"/>
		<updated>2018-03-24T10:31:48Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: /* Temas de Seminario de lógica computacional (2018) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: Programación funcional en Coq&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto] y [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código], [[R2 |Enunciado de ejercicios]] y [[Relación 2 | Solución colaborativa]].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_1&amp;diff=73</id>
		<title>Tema 1</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_1&amp;diff=73"/>
		<updated>2018-03-24T10:21:37Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* T1: Programación funcional en Coq *)&lt;br /&gt;
&lt;br /&gt;
Definition admit {T: Type} : T.  Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Datos y funciones &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Tipos enumerados  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo day cuyos constructores sean los días de&lt;br /&gt;
   la semana.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive day : Type :=&lt;br /&gt;
  | monday    : day&lt;br /&gt;
  | tuesday   : day&lt;br /&gt;
  | wednesday : day&lt;br /&gt;
  | thursday  : day&lt;br /&gt;
  | friday    : day&lt;br /&gt;
  | saturday  : day&lt;br /&gt;
  | sunday    : day.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función &lt;br /&gt;
      next_weekday :: day -&amp;gt; day &lt;br /&gt;
   tal que (next_weekday d) es el día laboral siguiente a d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition next_weekday (d:day) : day :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | monday    =&amp;gt; tuesday&lt;br /&gt;
  | tuesday   =&amp;gt; wednesday&lt;br /&gt;
  | wednesday =&amp;gt; thursday&lt;br /&gt;
  | thursday  =&amp;gt; friday&lt;br /&gt;
  | friday    =&amp;gt; monday&lt;br /&gt;
  | saturday  =&amp;gt; monday&lt;br /&gt;
  | sunday    =&amp;gt; monday&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el valor de las siguientes expresiones &lt;br /&gt;
      + (next_weekday friday)&lt;br /&gt;
      + (next_weekday (next_weekday saturday))&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (next_weekday friday).&lt;br /&gt;
(* ==&amp;gt; monday : day *)&lt;br /&gt;
&lt;br /&gt;
Compute (next_weekday (next_weekday saturday)).&lt;br /&gt;
(* ==&amp;gt; tuesday : day *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
      (next_weekday (next_weekday saturday)) = tuesday&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_next_weekday:&lt;br /&gt;
  (next_weekday (next_weekday saturday)) = tuesday.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Booleanos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo bool cuyos constructores son true y false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive bool : Type :=&lt;br /&gt;
  | true  : bool&lt;br /&gt;
  | false : bool.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      negb :: bool -&amp;gt; bool&lt;br /&gt;
   tal que (negb b) es la negación de b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition negb (b:bool) : bool :=&lt;br /&gt;
  match b with&lt;br /&gt;
  | true  =&amp;gt; false&lt;br /&gt;
  | false =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      andb :: bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (andb b1 b2) es la conjunción de b1 y b2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition andb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true =&amp;gt; b2&lt;br /&gt;
  | false =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      orb :: bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (orb b1 b2) es la disyunción de b1 y b2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition orb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true  =&amp;gt; true&lt;br /&gt;
  | false =&amp;gt; b2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar las siguientes propiedades&lt;br /&gt;
      (orb true  false) = true.&lt;br /&gt;
      (orb false false) = false.&lt;br /&gt;
      (orb false true)  = true.&lt;br /&gt;
      (orb true  true)  = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_orb1: (orb true  false) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb2: (orb false false) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb3: (orb false true)  = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_orb4: (orb true  true)  = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir los operadores (&amp;amp;&amp;amp;) y (||) como abreviaturas de las&lt;br /&gt;
   funciones andb y orb.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x &amp;amp;&amp;amp; y&amp;quot; := (andb x y).&lt;br /&gt;
Notation &amp;quot;x || y&amp;quot; := (orb x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      false || false || true = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_orb5: false || false || true = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Definir la función &lt;br /&gt;
      nandb :: bool -&amp;gt; bool -&amp;gt; bool &lt;br /&gt;
   tal que (nanb x y) se verifica si x e y no son verdaderos.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades de nand&lt;br /&gt;
      (nandb true  false) = true.&lt;br /&gt;
      (nandb false false) = true.&lt;br /&gt;
      (nandb false true)  = true.&lt;br /&gt;
      (nandb true  true)  = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition nandb (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with &lt;br /&gt;
  | true  =&amp;gt; negb b2&lt;br /&gt;
  | false =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_nandb1: (nandb true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb2: (nandb false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb3: (nandb false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_nandb4: (nandb true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb1 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
  | true =&amp;gt; negb b2&lt;br /&gt;
  | _    =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb11: (nandb1 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb12: (nandb1 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb13: (nandb1 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb14: (nandb1 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb2 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  match b1, b2 with&lt;br /&gt;
  | true, true =&amp;gt; false&lt;br /&gt;
  | _, _       =&amp;gt; true&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb21: (nandb2 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb22: (nandb2 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb23: (nandb2 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb24: (nandb2 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb3 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  if b1 then negb b2 else true.&lt;br /&gt;
&lt;br /&gt;
Example test_nandb31: (nandb3 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb32: (nandb3 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb33: (nandb3 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb34: (nandb3 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition nandb4 (b1:bool) (b2:bool) : bool :=&lt;br /&gt;
  negb (b1 &amp;amp;&amp;amp; b2).&lt;br /&gt;
&lt;br /&gt;
Example test_nandb41: (nandb4 true false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb42: (nandb4 false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb43: (nandb4 false true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_nandb44: (nandb4 true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Definir la función&lt;br /&gt;
      andb3 :: bool -&amp;gt; bool -&amp;gt; bool -&amp;gt; bool&lt;br /&gt;
   tal que (andb3 x y z) se verifica si x, y y z son verdaderos.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades de andb3&lt;br /&gt;
      (andb3 true  true  true)  = true.&lt;br /&gt;
      (andb3 false true  true)  = false.&lt;br /&gt;
      (andb3 true  false true)  = false.&lt;br /&gt;
      (andb3 true  true  false) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition andb3 (b1:bool) (b2:bool) (b3:bool) : bool :=&lt;br /&gt;
  match b1 with&lt;br /&gt;
   | true  =&amp;gt; andb b2 b3&lt;br /&gt;
   | false =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_andb31: (andb3 true true true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb32: (andb3 false true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb33: (andb3 true false true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
Example prop_andb34: (andb3 true true false) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Notation &amp;quot;x &amp;amp;&amp;amp; y&amp;quot; := (andb x y).&lt;br /&gt;
&lt;br /&gt;
Definition andb32 (b1:bool) (b2:bool) (b3:bool) : bool :=&lt;br /&gt;
  b1 &amp;amp;&amp;amp; b2 &amp;amp;&amp;amp; b3.&lt;br /&gt;
&lt;br /&gt;
Example test_andb321: (andb32 true true true) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb322: (andb32 false true true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb323: (andb32 true false true) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_andb324: (andb32 true true false) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Tipos de las funciones  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo de las siguientes expresiones&lt;br /&gt;
      + true&lt;br /&gt;
      + (negb true)&lt;br /&gt;
      + negb&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check true.&lt;br /&gt;
(* ===&amp;gt; true : bool *)&lt;br /&gt;
&lt;br /&gt;
Check (negb true).&lt;br /&gt;
(* ===&amp;gt; negb true : bool *)&lt;br /&gt;
&lt;br /&gt;
Check negb.&lt;br /&gt;
(* ===&amp;gt; negb : bool -&amp;gt; bool *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Tipos compuestos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo rgb cuyos constructores son red, green y&lt;br /&gt;
   blue. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive rgb : Type :=&lt;br /&gt;
  | red   : rgb&lt;br /&gt;
  | green : rgb&lt;br /&gt;
  | blue  : rgb.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo color cuyos constructores son black, white y&lt;br /&gt;
   primary, donde primary es una función de rgb en color.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive color : Type :=&lt;br /&gt;
  | black   : color&lt;br /&gt;
  | white   : color&lt;br /&gt;
  | primary : rgb -&amp;gt; color.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      monochrome :: color -&amp;gt; bool&lt;br /&gt;
   tal que (monochrome c) se verifica si c es monocromático.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition monochrome (c : color) : bool :=&lt;br /&gt;
  match c with&lt;br /&gt;
  | black     =&amp;gt; true&lt;br /&gt;
  | white     =&amp;gt; true&lt;br /&gt;
  | primary p =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      isred :: color -&amp;gt; bool&lt;br /&gt;
   tal que (isred c) se verifica si c es rojo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition isred (c : color) : bool :=&lt;br /&gt;
  match c with&lt;br /&gt;
  | black       =&amp;gt; false&lt;br /&gt;
  | white       =&amp;gt; false&lt;br /&gt;
  | primary red =&amp;gt; true&lt;br /&gt;
  | primary _   =&amp;gt; false&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Módulos  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Iniciar el módulo NatPlayground.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatPlayground.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Números naturales  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo nat de los números naturales con los&lt;br /&gt;
   constructores 0 (para el 0) y S (para el siguiente).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Inductive nat : Type :=&lt;br /&gt;
  | O : nat&lt;br /&gt;
  | S : nat -&amp;gt; nat.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      pred :: nat -&amp;gt; nat&lt;br /&gt;
   tal que (pred n) es el predecesor de n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Definition pred (n : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; O&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Finaliz el módulo NatPlayground.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatPlayground.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular el tipo y valor de la expresión (S (S (S (S O)))).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check (S (S (S (S O)))).&lt;br /&gt;
  (* ===&amp;gt; 4 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      minustwo :: nat -&amp;gt; nat&lt;br /&gt;
   tal que (minustwo n) es n-2. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition minustwo (n : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O        =&amp;gt; O&lt;br /&gt;
    | S O      =&amp;gt; O&lt;br /&gt;
    | S (S n&amp;#039;) =&amp;gt; n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión (minustwo 4).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Compute (minustwo 4).&lt;br /&gt;
  (* ===&amp;gt; 2 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Calcular et tipo de las funcionse S, pred y minustwo.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Check S.&lt;br /&gt;
Check pred.&lt;br /&gt;
Check minustwo.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      evenb :: nat -&amp;gt; bool&lt;br /&gt;
   tal que (evenb n) se verifica si n es par.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint evenb (n:nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O        =&amp;gt; true&lt;br /&gt;
  | S O      =&amp;gt; false&lt;br /&gt;
  | S (S n&amp;#039;) =&amp;gt; evenb n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      oddb :: nat -&amp;gt; bool&lt;br /&gt;
   tal que (oddb n) se verifica si n es impar.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition oddb (n:nat) : bool   :=   negb (evenb n).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      + oddb 1 = true.&lt;br /&gt;
      + oddb 4 = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_oddb1: oddb 1 = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_oddb2: oddb 4 = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Iniciar el módulo NatPlayground2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatPlayground2.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      plus :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (plus n m) es la suma de n y m. Por ejemplo,&lt;br /&gt;
      plus 3 2 = 5&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint plus (n : nat) (m : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; m&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; S (plus n&amp;#039; m)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Compute (plus 3 2).&lt;br /&gt;
(* ===&amp;gt; 5: nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      mult :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (mult n m) es el producto de n y m. Por ejemplo,&lt;br /&gt;
      mult 3 2 = 6&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint mult (n m : nat) : nat :=&lt;br /&gt;
  match n with&lt;br /&gt;
    | O    =&amp;gt; O&lt;br /&gt;
    | S n&amp;#039; =&amp;gt; plus m (mult n&amp;#039; m)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_mult1: (mult 2 3) = 6.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      minus :: nat -&amp;gt; nat -&amp;gt; nat &lt;br /&gt;
   tal que (minus n m) es la diferencia de n y m. Por ejemplo,&lt;br /&gt;
      mult 3 2 = 1&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
  &lt;br /&gt;
Fixpoint minus (n m:nat) : nat :=&lt;br /&gt;
  match (n, m) with&lt;br /&gt;
  | (O   , _)    =&amp;gt; O&lt;br /&gt;
  | (S _ , O)    =&amp;gt; n&lt;br /&gt;
  | (S n&amp;#039;, S m&amp;#039;) =&amp;gt; minus n&amp;#039; m&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Cerrar el módulo NatPlayground2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatPlayground2.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      exp : nat -&amp;gt;  nat -&amp;gt; nat&lt;br /&gt;
   tal que (exp x n) es la potencia n-ésima de x. Por ejemplo,&lt;br /&gt;
      exp 2 3 = 8&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint exp (base power : nat) : nat :=&lt;br /&gt;
  match power with&lt;br /&gt;
    | O   =&amp;gt; S O&lt;br /&gt;
    | S p =&amp;gt; mult base (exp base p)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Compute (exp 2 3).&lt;br /&gt;
(* ===&amp;gt; 8 : nat *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      factorial :: nat -&amp;gt; nat1&lt;br /&gt;
   tal que (factorial n) es el factorial de n. &lt;br /&gt;
&lt;br /&gt;
      (factorial 3) = 6.&lt;br /&gt;
      (factorial 5) = (mult 10 12).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5, angruicam1 *)&lt;br /&gt;
Fixpoint factorial (n:nat) : nat := &lt;br /&gt;
  match n with&lt;br /&gt;
  | O    =&amp;gt; 1&lt;br /&gt;
  | S n&amp;#039; =&amp;gt;  S n&amp;#039; * factorial n&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example prop_factorial1: (factorial 3) = 6.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_factorial2: (factorial 5) = (mult 10 12).&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir los operadores +, - y * como abreviaturas de  las&lt;br /&gt;
   funciones plus, minus y mult.  &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x + y&amp;quot; := (plus x y)&lt;br /&gt;
                       (at level 50, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
Notation &amp;quot;x - y&amp;quot; := (minus x y)&lt;br /&gt;
                       (at level 50, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
Notation &amp;quot;x * y&amp;quot; := (mult x y)&lt;br /&gt;
                       (at level 40, left associativity)&lt;br /&gt;
                       : nat_scope.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_nat : nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (beq_nat n m) se verifica si n y me son iguales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_nat (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; match m with&lt;br /&gt;
         | O    =&amp;gt; true&lt;br /&gt;
         | S m&amp;#039; =&amp;gt; false&lt;br /&gt;
         end&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; match m with&lt;br /&gt;
            | O    =&amp;gt; false&lt;br /&gt;
            | S m&amp;#039; =&amp;gt; beq_nat n&amp;#039; m&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      leb : nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (leb n m) se verifica si n es menor o igual que m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint leb (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O    =&amp;gt; true&lt;br /&gt;
  | S n&amp;#039; =&amp;gt; match m with&lt;br /&gt;
            | O    =&amp;gt; false&lt;br /&gt;
            | S m&amp;#039; =&amp;gt; leb n&amp;#039; m&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar las siguientes propiedades&lt;br /&gt;
      + (leb 2 2) = true.&lt;br /&gt;
      + (leb 2 4) = true.&lt;br /&gt;
      + (leb 4 2) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_leb1: (leb 2 2) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_leb2: (leb 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example test_leb3: (leb 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      blt_nat :: nat -&amp;gt; nat -&amp;gt; bool&lt;br /&gt;
   tal que (blt n m) se verifica si n es menor que m.&lt;br /&gt;
&lt;br /&gt;
   Demostrar las siguientes propiedades&lt;br /&gt;
      (blt_nat 2 2) = false.&lt;br /&gt;
      (blt_nat 2 4) = true.&lt;br /&gt;
      (blt_nat 4 2) = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Definition blt_nat (n m : nat) : bool :=&lt;br /&gt;
  match n with&lt;br /&gt;
  | O =&amp;gt; true&lt;br /&gt;
  | S n&amp;#039; =&amp;gt;&lt;br /&gt;
      match m with&lt;br /&gt;
      | O    =&amp;gt; false&lt;br /&gt;
      | S m&amp;#039; =&amp;gt; leb (S n&amp;#039;)  m&amp;#039;&lt;br /&gt;
      end&lt;br /&gt;
  end.                                   &lt;br /&gt;
&lt;br /&gt;
Example prop_blt_nat1: (blt_nat 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_blt_nat2: (blt_nat 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
Example prop_blt_nat3: (blt_nat 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Definition blt_nat2 (n m : nat) : bool :=&lt;br /&gt;
  negb (beq_nat (m-n) 0).&lt;br /&gt;
&lt;br /&gt;
Example test_blt_nat21: (blt_nat2 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_blt_nat22: (blt_nat2 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
Example test_blt_nat23: (blt_nat2 4 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por simplificación &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que el 0 es el elemento neutro por la izquierda de&lt;br /&gt;
   la suma de los números naturales.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración *)&lt;br /&gt;
Theorem plus_O_n : forall n : nat, 0 + n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración *)&lt;br /&gt;
Theorem plus_O_n&amp;#039; : forall n : nat, 0 + n = n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la suma de 1 y n es el siguiente de n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_1_l : forall n:nat, 1 + n = S n.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que el producto de 0 por n es 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem mult_0_l : forall n:nat, 0 * n = 0.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por reescritura &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que si n = m, entonces n + n = m + m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Theorem plus_id_example : forall n m:nat,&lt;br /&gt;
  n = m -&amp;gt;&lt;br /&gt;
  n + n = m + m.&lt;br /&gt;
&lt;br /&gt;
Proof.&lt;br /&gt;
  (* move both quantifiers into the context: *)&lt;br /&gt;
  intros n m.&lt;br /&gt;
  (* move the hypothesis into the context: *)&lt;br /&gt;
  intros H.&lt;br /&gt;
  (* rewrite the goal using the hypothesis: *)&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Demostrar que si n = m y m = o, entonces n + m = m + o.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem plus_id_exercise: forall n m o : nat,&lt;br /&gt;
  n = m -&amp;gt; m = o -&amp;gt; n + m = m + o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  intros o Ho.&lt;br /&gt;
  rewrite -&amp;gt; Ho.&lt;br /&gt;
  intros H.&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem plus_id_exercise2 : forall n m o : nat,&lt;br /&gt;
  n = m -&amp;gt; m = o -&amp;gt; n + m = m + o.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m o H1 H2.&lt;br /&gt;
  rewrite -&amp;gt; H1.&lt;br /&gt;
  rewrite -&amp;gt; H2.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que (0 + n) * m = n * m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem mult_0_plus : forall n m : nat,&lt;br /&gt;
  (0 + n) * m = n * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  rewrite -&amp;gt; plus_O_n.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar que si m = S n, entonces m * (1 + n) = m * m.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem mult_S_1 : forall n m : nat,&lt;br /&gt;
  m = S n -&amp;gt;&lt;br /&gt;
  m * (1 + n) = m * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m.&lt;br /&gt;
  intros H.&lt;br /&gt;
  rewrite -&amp;gt; H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed. &lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem mult_S_12 : forall n m : nat,&lt;br /&gt;
  m = S n -&amp;gt;&lt;br /&gt;
  m * (1 + n) = m * m.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n m H.&lt;br /&gt;
  rewrite H.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Demostraciones por análisis de casos &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que n + 1 es distinto de 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1º intento *)&lt;br /&gt;
Theorem plus_1_neq_0_firsttry : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n.&lt;br /&gt;
  simpl.  (* does nothing! *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
(* 2º intento *)&lt;br /&gt;
Theorem plus_1_neq_0 : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n as [| n&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la negación es involutiva; es decir, la&lt;br /&gt;
   negación de la negación de b es b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem negb_involutive : forall b : bool,&lt;br /&gt;
  negb (negb b) = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b. destruct b.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* 1ª demostración *)&lt;br /&gt;
Theorem andb_commutative : forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* 2ª demostración *)&lt;br /&gt;
Theorem andb_commutative&amp;#039; : forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  { destruct c.&lt;br /&gt;
    { reflexivity. }&lt;br /&gt;
    { reflexivity. } }&lt;br /&gt;
  { destruct c.&lt;br /&gt;
    { reflexivity. }&lt;br /&gt;
    { reflexivity. } }&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es asociativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem andb3_exchange :&lt;br /&gt;
  forall b c d, andb (andb b c) d = andb (andb b d) c.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c d. destruct b.&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
  - destruct c.&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
    { destruct d.&lt;br /&gt;
      - reflexivity.&lt;br /&gt;
      - reflexivity. }&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que n + 1 es distinto de 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem plus_1_neq_0&amp;#039; : forall n : nat,&lt;br /&gt;
  beq_nat (n + 1) 0 = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [|n].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la conjunción es conmutativa.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem andb_commutative&amp;#039;&amp;#039; :&lt;br /&gt;
  forall b c, andb b c = andb c b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que si andb b c = true, entonces c = true.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem andb_true_elim2 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct b.&lt;br /&gt;
  - intros H. rewrite &amp;lt;-H. reflexivity.&lt;br /&gt;
  - intros H. rewrite &amp;lt;-H. destruct false.&lt;br /&gt;
    + reflexivity.&lt;br /&gt;
    + destruct c. rewrite &amp;lt;-H. reflexivity. reflexivity. &lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem andb_true_elim22 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] [] [].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* jorcatote *)&lt;br /&gt;
Theorem andb_true_elim23 : forall b c : bool,&lt;br /&gt;
  andb b c = true -&amp;gt; c = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros b c. destruct c.&lt;br /&gt;
    - reflexivity.   &lt;br /&gt;
    - destruct b.&lt;br /&gt;
      + simpl. intros h. rewrite h. reflexivity.&lt;br /&gt;
      + simpl. intros h. rewrite h. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Dmostrar que 0 es distinto de n + 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* alerodrod5 *)&lt;br /&gt;
Theorem zero_nbeq_plus_1: forall n : nat,&lt;br /&gt;
  beq_nat 0 (n + 1) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. destruct n.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 *)&lt;br /&gt;
Theorem zero_nbeq_plus_12 : forall n : nat,&lt;br /&gt;
  beq_nat 0 (n + 1) = false.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [| n&amp;#039;].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios complementarios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Demostrar que&lt;br /&gt;
      forall (f : bool -&amp;gt; bool),&lt;br /&gt;
        (forall (x : bool), f x = x) -&amp;gt; &lt;br /&gt;
        forall (b : bool), f (f b) = b.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1, alerodrod5 *)&lt;br /&gt;
Theorem identity_fn_applied_twice :&lt;br /&gt;
  forall (f : bool -&amp;gt; bool),&lt;br /&gt;
  (forall (x : bool), f x = x) -&amp;gt;&lt;br /&gt;
  forall (b : bool), f (f b) = b.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros f x b.&lt;br /&gt;
  rewrite x.&lt;br /&gt;
  rewrite x.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Demostrar que&lt;br /&gt;
      forall (b c : bool),&lt;br /&gt;
        (andb b c = orb b c) -&amp;gt; b = c.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1 alerodrod5 *)&lt;br /&gt;
Theorem andb_eq_orb :&lt;br /&gt;
  forall (b c : bool),&lt;br /&gt;
  (andb b c = orb b c) -&amp;gt;&lt;br /&gt;
  b = c.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros [] c.&lt;br /&gt;
  - simpl. intros H. rewrite H. reflexivity.&lt;br /&gt;
  - simpl. intros H. rewrite H. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. En este ejercicio se considera la siguiente&lt;br /&gt;
   representación de los números naturales&lt;br /&gt;
      Inductive nat2 : Type :=&lt;br /&gt;
        | C  : nat2&lt;br /&gt;
        | D  : nat2 -&amp;gt; nat2&lt;br /&gt;
        | SD : nat2 -&amp;gt; nat2.&lt;br /&gt;
   donde C representa el cero, D el doble y SD el siguiente del doble.&lt;br /&gt;
&lt;br /&gt;
   Definir la función&lt;br /&gt;
      nat2Anat :: nat2 -&amp;gt; nat&lt;br /&gt;
   tal que (nat2Anat x) es el número natural representado por x. &lt;br /&gt;
&lt;br /&gt;
   Demostrar que &lt;br /&gt;
      nat2Anat (SD (SD C))     = 3&lt;br /&gt;
      nat2Anat (D (SD (SD C))) = 6.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* angruicam1, alerodrod5 *)&lt;br /&gt;
Inductive nat2 : Type :=&lt;br /&gt;
  | C  : nat2&lt;br /&gt;
  | D  : nat2 -&amp;gt; nat2&lt;br /&gt;
  | SD : nat2 -&amp;gt; nat2.&lt;br /&gt;
 &lt;br /&gt;
Fixpoint nat2Anat (x:nat2) : nat :=&lt;br /&gt;
  match x with&lt;br /&gt;
  | C =&amp;gt; O&lt;br /&gt;
  | D n =&amp;gt; 2*nat2Anat n&lt;br /&gt;
  | SD n =&amp;gt; (2*nat2Anat n)+1&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example prop_nat2Anat1: (nat2Anat (SD (SD C))) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example prop_nat2Anat2: (nat2Anat (D (SD (SD C)))) = 6.&lt;br /&gt;
Proof. reflexivity. Qed.&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/SLC2018/index.php?title=Temas&amp;diff=72</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=72"/>
		<updated>2018-03-24T10:12:33Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: Programación funcional en Coq&lt;br /&gt;
** [[Tema 1 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código], [[R1 |Enunciado de ejercicios]] y [[Relación 1 | Solución colaborativa]].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [[Tema 2 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código], [[R2 |Enunciado de ejercicios]] y [[Relación 2 | Solución colaborativa]].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [[Tema 3 |Exposición]], [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Miriam Medrán Navarro&lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra (Tema 3)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=69</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=69"/>
		<updated>2018-03-22T14:16:53Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: Programación funcional en Coq&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código], [[Tema 1 |Exposición]], [[R1 |Enunciado de ejercicios]] y [[Relación 1 | Solución colaborativa]].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código], [[Tema 2 |Exposición]], [[R2 |Enunciado de ejercicios]] y [[Relación 2 | Solución colaborativa]].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código], [[Tema 3 |Exposición y ejercicios]].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra &lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
** Borja Sierra Miranda&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Miriam Medrán Navarro&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=67</id>
		<title>Temas</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Temas&amp;diff=67"/>
		<updated>2018-03-22T07:22:32Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Temas de &amp;#039;&amp;#039;Seminario de lógica computacional (2018)&amp;#039;&amp;#039; ==&lt;br /&gt;
&lt;br /&gt;
En esta página se irán publicando los temas conforme se vayan estudiando.&lt;br /&gt;
&lt;br /&gt;
* Tema 0: Introducción al Seminario &lt;br /&gt;
** [http://www.seas.upenn.edu/~cis500/current/lectures/lec01.pdf Introducción de B. Pierce al curso &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html Introducción del libro &amp;quot;Software foundations&amp;quot;].&lt;br /&gt;
* Tema 1: Programación funcional en Coq&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Basics.v Código], [[Tema 1 |Exposición]], [[R1 |Enunciado de ejercicios]] y [[Relación 1 | Solución colaborativa]].&lt;br /&gt;
* Tema 2: Demostraciones por inducción en Coq&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Induction.v Código], [[Tema 2 |Exposición]], [[R2 |Enunciado de ejercicios]] y [[Relación 2 | Solución colaborativa]].&lt;br /&gt;
* Tema 3: Datos estructurados en Coq&lt;br /&gt;
** [https://softwarefoundations.cis.upenn.edu/lf-current/Lists.html Texto], [http://www.seas.upenn.edu/~cis500/current/sf/lf-current/Lists.v Código], [[Tema 3 |Exposición y ejercicios]].&lt;br /&gt;
&lt;br /&gt;
=== Ponentes ===&lt;br /&gt;
&lt;br /&gt;
* Ponentes de las próximas sesiones:&lt;br /&gt;
** Jorge Catarecha Otero-Saavedra &lt;br /&gt;
** Samuel Ortiz Morales&lt;br /&gt;
* Ponentes de las sesiones anteriores:&lt;br /&gt;
** Ángel Ruiz Campos (Tema 1)&lt;br /&gt;
** Alejandro Rodríguez Rodríguez (Tema 2)&lt;br /&gt;
&lt;br /&gt;
=== Participantes === &lt;br /&gt;
&lt;br /&gt;
Los participantes en el Seminario son&lt;br /&gt;
* Alejandro Rodriguez Rodríguez  &lt;br /&gt;
* Ángel Ruiz Campos&lt;br /&gt;
* Borja Sierra Miranda&lt;br /&gt;
* Elías Guisado Villalgordo&lt;br /&gt;
* Jorge Catarecha Otero-Saavedra &lt;br /&gt;
* Marina Jiménez Comez&lt;br /&gt;
* Mencía Veas Lerdo de Tejada&lt;br /&gt;
* Miriam Medrán Navarro&lt;br /&gt;
* Samuel Ortiz Morales&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=66</id>
		<title>Tema 3</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=66"/>
		<updated>2018-03-22T06:54:35Z</updated>

		<summary type="html">&lt;p&gt;Jalonso: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* Datos estructurados en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export Induction.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module NatList. &lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Pares de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. El tipo de los números naturales es natprod y su&lt;br /&gt;
   constructor es pair.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natprod : Type :=&lt;br /&gt;
  pair : nat -&amp;gt; nat -&amp;gt; natprod.&lt;br /&gt;
&lt;br /&gt;
Check (pair 3 5).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      fst : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (fst p) es la primera componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (pair 3 5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (pair 3 5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      snd : natprod -&amp;gt; nat&lt;br /&gt;
   tal que (snd p) es la segunda componente de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | pair x y =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x,y) como una abreviaura de (pair x y).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;( x , y )&amp;quot; := (pair x y).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Evaluar la expresión &lt;br /&gt;
      fst (3,5)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Eval compute in (fst (3,5)).&lt;br /&gt;
(* ===&amp;gt; 3 *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función fst usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition fst&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Redefinir la función snd usando la abreviatura de pares.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition snd&amp;#039; (p : natprod) : nat := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; y&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      swap_pair : natprod -&amp;gt; natprod&lt;br /&gt;
   tal que (swap_pair p) es el par obtenido intercambiando las&lt;br /&gt;
   componentes de p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition swap_pair (p : natprod) : natprod := &lt;br /&gt;
  match p with&lt;br /&gt;
  | (x,y) =&amp;gt; (y,x)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todos los naturales&lt;br /&gt;
      (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing&amp;#039; : forall (n m : nat),&lt;br /&gt;
  (n,m) = (fst (n,m), snd (n,m)).&lt;br /&gt;
Proof.&lt;br /&gt;
  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que para todo par de naturales&lt;br /&gt;
      p = (fst p, snd p).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing_stuck : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  simpl. (* No reduce nada. *)&lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem surjective_pairing : forall (p : natprod),&lt;br /&gt;
  p = (fst p, snd p).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros p.  destruct p as [n m].  simpl.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 1. Demostrar que para todo par de naturales p,&lt;br /&gt;
      (snd p, fst p) = swap_pair p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem snd_fst_is_swap : forall (p : natprod),&lt;br /&gt;
  (snd p, fst p) = swap_pair p.&lt;br /&gt;
Admitted.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 2. Demostrar que para todo par de naturales p,&lt;br /&gt;
      fst (swap_pair p) = snd p.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem fst_swap_is_snd : forall (p : natprod),&lt;br /&gt;
  fst (swap_pair p) = snd p.&lt;br /&gt;
Admitted.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Listas de números &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. natlist es la lista de los números naturales y sus&lt;br /&gt;
   constructores son &lt;br /&gt;
   + nil (la lista vacía) y &lt;br /&gt;
   + cons (tal que (cons x ys) es la lista obtenida añadiéndole x a ys. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natlist : Type :=&lt;br /&gt;
  | nil  : natlist&lt;br /&gt;
  | cons : nat -&amp;gt; natlist -&amp;gt; natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la constante &lt;br /&gt;
      mylist : natlist&lt;br /&gt;
   que es la lista cuyos elementos son 1, 2 y 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist := cons 1 (cons 2 (cons 3 nil)).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (x :: ys) como una abreviatura de &lt;br /&gt;
   (cons x ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x :: l&amp;quot; := (cons x l)&lt;br /&gt;
                     (at level 60, right associativity).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación de las listas finitas escribiendo sus&lt;br /&gt;
   elementos entre corchetes y separados por puntos y comas.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;[ ]&amp;quot; := nil.&lt;br /&gt;
Notation &amp;quot;[ x ; .. ; y ]&amp;quot; := (cons x .. (cons y nil) ..).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Distintas representaciones de mylist.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition mylist1 := 1 :: (2 :: (3 :: nil)).&lt;br /&gt;
Definition mylist2 := 1 :: 2 :: 3 :: nil.&lt;br /&gt;
Definition mylist3 := [1;2;3].&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Repeat  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      repeat : nat -&amp;gt; nat -&amp;gt; natlist&lt;br /&gt;
   tal que (repeat n k) es la lista formada por k veces el número n.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint repeat (n count : nat) : natlist :=&lt;br /&gt;
  match count with&lt;br /&gt;
  | O        =&amp;gt; nil&lt;br /&gt;
  | S count&amp;#039; =&amp;gt; n :: (repeat n count&amp;#039;)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Length  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      length : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (length xs) es el número de elementos de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint length (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; O&lt;br /&gt;
  | h :: t =&amp;gt; S (length t)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Append  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      append : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (append xs ys) es la concatenación de xs e ys.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Fixpoint app (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil    =&amp;gt; l2&lt;br /&gt;
  | h :: t =&amp;gt; h :: (app t l2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la notación (xs ++ ys) como una abreviaura de &lt;br /&gt;
   (append xs ys).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Notation &amp;quot;x ++ y&amp;quot; := (app x y)&lt;br /&gt;
                     (right associativity, at level 60).&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
      nil     ++ [4;5] = [4;5].&lt;br /&gt;
      [1;2;3] ++ nil   = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_app1: [1;2;3] ++ [4;5] = [1;2;3;4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app2: nil ++ [4;5] = [4;5].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_app3: [1;2;3] ++ nil = [1;2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Head y tail  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      hd : nat -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (hd d xs) es el primer elemento de xs o d, si xs es la lista&lt;br /&gt;
   vacía. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd (default:nat) (l:natlist) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; default&lt;br /&gt;
  | h :: t =&amp;gt; h&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      tl : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (tl xs) es el resto de xs.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition tl (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; t&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que &lt;br /&gt;
       hd 0 [1;2;3] = 1.&lt;br /&gt;
       hd 0 []      = 0.&lt;br /&gt;
       tl [1;2;3]   = [2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Example test_hd1: hd 0 [1;2;3] = 1.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_hd2: hd 0 [] = 0.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_tl: tl [1;2;3] = [2;3].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 3. Definir la función&lt;br /&gt;
      nonzeros : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (nonzeros xs) es la lista de los elementos de xs distintos de&lt;br /&gt;
   cero. Por ejemplo,&lt;br /&gt;
      nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nonzeros (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | a::bs =&amp;gt; match a with&lt;br /&gt;
            | 0 =&amp;gt; nonzeros bs &lt;br /&gt;
            | _ =&amp;gt;  a:: nonzeros bs end&lt;br /&gt;
 end.&lt;br /&gt;
Example test_nonzeros: nonzeros [0;1;0;2;3;0;0] = [1;2;3].&lt;br /&gt;
Proof. simpl. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 4. Definir la función&lt;br /&gt;
      oddmembers : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (oddmembers xs) es la lista de los elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint oddmembers (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t::xs =&amp;gt; if oddb t then t :: oddmembers xs else oddmembers xs&lt;br /&gt;
  end.&lt;br /&gt;
 &lt;br /&gt;
Example test_oddmembers: oddmembers [0;1;0;2;3;0;0] = [1;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Definir la función&lt;br /&gt;
      countoddmembers : natlist -&amp;gt; nat&lt;br /&gt;
   tal que (countoddmembers xs) es el número de elementos impares de&lt;br /&gt;
   xs. Por ejemplo,&lt;br /&gt;
      countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
      countoddmembers [0;2;4]       = 0.&lt;br /&gt;
      countoddmembers nil           = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition countoddmembers (l:natlist) : nat :=&lt;br /&gt;
 length (oddmembers l). &lt;br /&gt;
&lt;br /&gt;
Example test_countoddmembers1: countoddmembers [1;0;3;1;4;5] = 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers2: countoddmembers [0;2;4] = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_countoddmembers3: countoddmembers nil = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Definir la función&lt;br /&gt;
      alternate : natlist -&amp;gt; natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (alternate xs ys) es la lista obtenida intercalando los&lt;br /&gt;
   elementos de xs e ys. Por ejemplo,&lt;br /&gt;
      alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
      alternate [1] [4;5;6]     = [1;4;5;6].&lt;br /&gt;
      alternate [1;2;3] [4]     = [1;4;2;3].&lt;br /&gt;
      alternate [] [20;30]      = [20;30].&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint alternate (l1 l2 : natlist) : natlist :=&lt;br /&gt;
  match l1 with&lt;br /&gt;
  | nil =&amp;gt; l2&lt;br /&gt;
  | t::xs =&amp;gt; match l2 with&lt;br /&gt;
            | nil =&amp;gt; t::xs&lt;br /&gt;
            | p::ys =&amp;gt; t::p::alternate xs ys end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_alternate1: alternate [1;2;3] [4;5;6] = [1;4;2;5;3;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate2: alternate [1] [4;5;6] = [1;4;5;6].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate3: alternate [1;2;3] [4] = [1;4;2;3].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_alternate4: alternate [] [20;30] = [20;30].&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Multiconjuntos como listas &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* Un multiconjunto es como un conjunto donde los elementos pueden&lt;br /&gt;
   repetirse más de una vez. Podemos implementarlos como listas.  *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo baf de los multiconjuntos de números&lt;br /&gt;
   naturales. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition bag := natlist.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Definir la función&lt;br /&gt;
      count : nat -&amp;gt; bag -&amp;gt; nat &lt;br /&gt;
   tal que (count v s) es el número des veces que aparece el elemento v&lt;br /&gt;
   en el multiconjunto s. Por ejemplo,&lt;br /&gt;
      count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
      count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint count (v:nat) (s:bag) : nat :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil   =&amp;gt; 0&lt;br /&gt;
  | t::xs =&amp;gt; if beq_nat t v&lt;br /&gt;
            then 1 + count v xs&lt;br /&gt;
            else count v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_count1: count 1 [1;2;3;1;4;1] = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_count2: count 6 [1;2;3;1;4;1] = 0.&lt;br /&gt;
Proof. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Definir la función&lt;br /&gt;
      sum : bag -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (sum xs ys) es la suma de los multiconjuntos xs e ys. Por&lt;br /&gt;
   ejemplo, &lt;br /&gt;
      count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition sum : bag -&amp;gt; bag -&amp;gt; bag := app.&lt;br /&gt;
&lt;br /&gt;
Example test_sum1: count 1 (sum [1;2;3] [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 9. Definir la función&lt;br /&gt;
      add : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (add x ys) es el multiconjunto obtenido añadiendo el elemento&lt;br /&gt;
   x al multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
      count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition add (v:nat) (s:bag) : bag :=&lt;br /&gt;
  v :: s.&lt;br /&gt;
&lt;br /&gt;
Example test_add1: count 1 (add 1 [1;4;1]) = 3.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_add2: count 5 (add 1 [1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 10. Definir la función&lt;br /&gt;
      member : nat -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (member x ys) se verfica si x pertenece al multiconjunto&lt;br /&gt;
   ys. Por ejemplo,  &lt;br /&gt;
      member 1 [1;4;1] = true.&lt;br /&gt;
      member 2 [1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition member (v:nat) (s:bag) : bool := &lt;br /&gt;
  if beq_nat 0 (count v s)&lt;br /&gt;
  then false&lt;br /&gt;
  else true.&lt;br /&gt;
&lt;br /&gt;
Example test_member1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
Definition member2 (v:nat) (s:bag) : bool :=&lt;br /&gt;
  negb (beq_nat O (count v s)).&lt;br /&gt;
&lt;br /&gt;
Example test_member2_1: member 1 [1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_member2_2: member 2 [1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 11. Definir la función&lt;br /&gt;
      remove_one : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_one x ys) es el multiconjunto obtenido eliminando una&lt;br /&gt;
   ocurrencia de x en el multiconjunto ys. Por ejemplo, &lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;1])     = 0.&lt;br /&gt;
      count 4 (remove_one 5 [2;1;4;5;1;4])   = 2.&lt;br /&gt;
      count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_one (v:nat) (s:bag) : bag :=&lt;br /&gt;
  match s with&lt;br /&gt;
  | nil     =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then xs&lt;br /&gt;
               else t :: remove_one v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_one1: count 5 (remove_one 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one2: count 5 (remove_one 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one3: count 4 (remove_one 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_one4: count 5 (remove_one 5 [2;1;5;4;5;1;4]) = 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 12. Definir la función&lt;br /&gt;
      remove_all : nat -&amp;gt; bag -&amp;gt; bag&lt;br /&gt;
   tal que (remove_all x ys) es el multiconjunto obtenido eliminando&lt;br /&gt;
   todas las ocurrencias de x en el multiconjunto ys. Por ejemplo,&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;1])           = 0.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;4;1])             = 0.&lt;br /&gt;
      count 4 (remove_all 5 [2;1;4;5;1;4])         = 2.&lt;br /&gt;
      count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint remove_all (v:nat) (s:bag) : bag :=&lt;br /&gt;
   match s with&lt;br /&gt;
  | nil =&amp;gt; nil&lt;br /&gt;
  | t :: xs =&amp;gt; if beq_nat t v&lt;br /&gt;
               then remove_all v xs&lt;br /&gt;
               else t :: remove_all v xs&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_remove_all1: count 5 (remove_all 5 [2;1;5;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all2: count 5 (remove_all 5 [2;1;4;1]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all3: count 4 (remove_all 5 [2;1;4;5;1;4]) = 2.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_remove_all4: count 5 (remove_all 5 [2;1;5;4;5;1;4;5;1;4]) = 0.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 13. Definir la función&lt;br /&gt;
      subset : bag -&amp;gt; bag -&amp;gt; bool&lt;br /&gt;
   tal que (subset xs ys) se verifica si xs es un sub,ulticonjunto de&lt;br /&gt;
   ys. Por ejemplo,&lt;br /&gt;
      subset [1;2]   [2;1;4;1] = true.&lt;br /&gt;
      subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint subset (s1:bag) (s2:bag) : bool :=&lt;br /&gt;
  match s1 with&lt;br /&gt;
  | nil   =&amp;gt; true&lt;br /&gt;
  | x::xs =&amp;gt; member x s2 &amp;amp;&amp;amp; subset xs (remove_one x s2)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_subset1: subset [1;2] [2;1;4;1] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_subset2: subset [1;2;2] [2;1;4;1] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 14. Escribir un teorema sobre multiconjuntos con las funciones&lt;br /&gt;
   count y add y probarlo. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_theorem : forall s1 s2 : bag, forall n : nat,&lt;br /&gt;
  count n s1 + count n s2 = count n (app s1 s2).                 &lt;br /&gt;
Proof.&lt;br /&gt;
  intros s1 s2 n. induction s1 as [|s s&amp;#039;].&lt;br /&gt;
 - simpl. reflexivity.&lt;br /&gt;
 - simpl. destruct (beq_nat s n).&lt;br /&gt;
    + simpl. rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
    + rewrite IHs&amp;#039;. reflexivity.&lt;br /&gt;
 Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Razonamiento sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      [] ++ l = l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem nil_app : forall l:natlist,&lt;br /&gt;
  [] ++ l = l.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que, para toda lista de naturales l,&lt;br /&gt;
      pred (length l) = length (tl l)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem tl_length_pred : forall l:natlist,&lt;br /&gt;
  pred (length l) = length (tl l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. destruct l as [| n l&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons n l&amp;#039; *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Inducción sobre listas&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que la concatenación de listas de naturales es&lt;br /&gt;
   asociativa. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc : forall l1 l2 l3 : natlist,&lt;br /&gt;
  (l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons n l1&amp;#039; *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Comentar los nombres dados en la hipótesis de inducción. *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Inversa de una lista  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      rev : natlist -&amp;gt; natlist&lt;br /&gt;
   tal que (rev xs) es la inversa de xs. Por ejemplo,&lt;br /&gt;
      rev [1;2;3] = [3;2;1].&lt;br /&gt;
      rev nil     = nil.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint rev (l:natlist) : natlist :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil    =&amp;gt; nil&lt;br /&gt;
  | h :: t =&amp;gt; rev t ++ [h]&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_rev1: rev [1;2;3] = [3;2;1].&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
Example test_rev2: rev nil = nil.&lt;br /&gt;
Proof. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§§ Propiedaes de la función rev  &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Demostrar que&lt;br /&gt;
      length (rev l) = length l&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length_firsttry : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = [] *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = n :: l&amp;#039; *)&lt;br /&gt;
    (* Probamos simplificando *)&lt;br /&gt;
    simpl.&lt;br /&gt;
    rewrite &amp;lt;- IHl&amp;#039;.&lt;br /&gt;
    (* Nos encontramos sin más que hacer, así que buscamos un lema que&lt;br /&gt;
       nos ayude. *) &lt;br /&gt;
Abort.&lt;br /&gt;
&lt;br /&gt;
Theorem app_length : forall l1 l2 : natlist,&lt;br /&gt;
  length (l1 ++ l2) = (length l1) + (length l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [| n l1&amp;#039; IHl1&amp;#039;].&lt;br /&gt;
  - (* l1 = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l1 = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl1&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* Ahora completamos la prueba original. *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_length : forall l : natlist,&lt;br /&gt;
  length (rev l) = length l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| n l&amp;#039; IHl&amp;#039;].&lt;br /&gt;
  - (* l = nil *)&lt;br /&gt;
    reflexivity.&lt;br /&gt;
  - (* l = cons *)&lt;br /&gt;
    simpl. rewrite -&amp;gt; app_length, plus_comm.&lt;br /&gt;
    simpl. rewrite -&amp;gt; IHl&amp;#039;. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Ejercicios &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 15. Demostrar que la lista vacía es el elemento neutro por la&lt;br /&gt;
   derecha de la concatenación de listas. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_nil_r : forall l : natlist,&lt;br /&gt;
  l ++ [] = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l. induction l as [| x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 16. Demostrar que rev es un endomorfismo en (natlist,++)&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
Theorem rev_app_distr: forall l1 l2 : natlist,&lt;br /&gt;
  rev (l1 ++ l2) = rev l2 ++ rev l1.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - simpl. rewrite app_nil_r. reflexivity.&lt;br /&gt;
  - simpl. rewrite HI, app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 17. Demostrar que rev es involutiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem rev_involutive : forall l : natlist,&lt;br /&gt;
  rev (rev l) = l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite rev_app_distr. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 18. Demostrar que&lt;br /&gt;
      l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem app_assoc4 : forall l1 l2 l3 l4 : natlist,&lt;br /&gt;
  l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2 l3 l4. rewrite app_assoc. rewrite app_assoc. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 19. Demostrar que al concatenar dos listas no aparecen ni&lt;br /&gt;
   desaparecen ceros. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Lemma nonzeros_app : forall l1 l2 : natlist,&lt;br /&gt;
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l1 l2. induction l1 as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 20. Definir la función&lt;br /&gt;
      beq_natlist : natlist -&amp;gt; natlist -&amp;gt; bool&lt;br /&gt;
   tal que (beq_natlist xs ys) se verifica si las listas xs e ys son&lt;br /&gt;
   iguales. Por ejemplo,&lt;br /&gt;
      beq_natlist nil nil         = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
      beq_natlist [1;2;3] [1;2;4] = false. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint beq_natlist (l1 l2 : natlist) : bool:=&lt;br /&gt;
  match l1, l2 with&lt;br /&gt;
  | nil,   nil   =&amp;gt; true&lt;br /&gt;
  | x::xs, y::ys =&amp;gt; beq_nat x y &amp;amp;&amp;amp; beq_natlist xs ys&lt;br /&gt;
  | _, _         =&amp;gt; false&lt;br /&gt;
 end.&lt;br /&gt;
&lt;br /&gt;
Example test_beq_natlist1: (beq_natlist nil nil = true).&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist2: beq_natlist [1;2;3] [1;2;3] = true.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_beq_natlist3: beq_natlist [1;2;3] [1;2;4] = false.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 21. Demostrar que la igualdad de listas cumple la propiedad&lt;br /&gt;
   reflexiva. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_natlist_refl : forall l:natlist,&lt;br /&gt;
  true = beq_natlist l l.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction l as [|n xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. rewrite &amp;lt;- HI. replace (beq_nat n n) with true.  reflexivity.&lt;br /&gt;
    + rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   §§ Ejercicios: 1ª parte &lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 22. Demostrar que al incluir un elemento en un multiconjunto,&lt;br /&gt;
   ese elemento aparece al menos una vez en el resultado.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem count_member_nonzero : forall (s : bag),&lt;br /&gt;
  leb 1 (count 1 (1 :: s)) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
 intro s.  simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 23. Demostrar que cada número natural es menor o igual que&lt;br /&gt;
   su siguiente. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem ble_n_Sn : forall n,&lt;br /&gt;
  leb n (S n) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n. induction n as [| n&amp;#039; IHn&amp;#039;].&lt;br /&gt;
  - (* 0 *)&lt;br /&gt;
    simpl.  reflexivity.&lt;br /&gt;
  - (* S n&amp;#039; *)&lt;br /&gt;
    simpl.  rewrite IHn&amp;#039;.  reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 24. Demostrar que al borrar una ocurrencia de 0 de un&lt;br /&gt;
   multiconjunto el número de ocurrencias de 0 en el resultado es menor&lt;br /&gt;
   o igual que en el original.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem remove_decreases_count: forall (s : bag),&lt;br /&gt;
  leb (count 0 (remove_one 0 s)) (count 0 s) = true.&lt;br /&gt;
Proof.&lt;br /&gt;
  induction s as [|x xs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct x.&lt;br /&gt;
    + rewrite ble_n_Sn. reflexivity.&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
Qed.    &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 25. Escribir un teorema con las funciones count y sum de los&lt;br /&gt;
   multiconjuntos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem bag_count_sum: forall n : nat, forall b1 b2 : bag,&lt;br /&gt;
  count n b1 + count n b2 = count n (sum b1 b2).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros n b1 b2. induction b1 as [|b bs HI].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. destruct (beq_nat b n).&lt;br /&gt;
    + simpl. rewrite HI. reflexivity.&lt;br /&gt;
    + rewrite HI. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 26. Demostrar que la función rev es inyectiva; es decir,&lt;br /&gt;
      forall (l1 l2 : natlist), rev l1 = rev l2 -&amp;gt; l1 = l2.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Opcionales&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_bad : natlist -&amp;gt; n -&amp;gt; nat&lt;br /&gt;
   tal que (nth_bad xs n) es el n-ésimo elemento de la lista xs y 42 si&lt;br /&gt;
   la lista tiene menos de n elementos. &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_bad (l:natlist) (n:nat) : nat :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; 42  (* un valor arbitrario *)&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; a&lt;br /&gt;
               | false =&amp;gt; nth_bad l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo natoption con los contructores&lt;br /&gt;
      Some : nat -&amp;gt; natoption&lt;br /&gt;
      None : natoption.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive natoption : Type :=&lt;br /&gt;
  | Some : nat -&amp;gt; natoption&lt;br /&gt;
  | None : natoption.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      nth_error : natlist -&amp;gt; nat -&amp;gt; natoption&lt;br /&gt;
   tal que (nth_error xs n) es el n-ésimo elemento de la lista xs o None&lt;br /&gt;
   si la lista tiene menos de n elementos. Por ejemplo,&lt;br /&gt;
      nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
      nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
      nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil     =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; match beq_nat n O with&lt;br /&gt;
               | true  =&amp;gt; Some a&lt;br /&gt;
               | false =&amp;gt; nth_error l&amp;#039; (pred n)&lt;br /&gt;
               end&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error2 : nth_error [4;5;6;7] 3 = Some 7.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_nth_error3 : nth_error [4;5;6;7] 9 = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* Introduciendo condicionales nos queda: *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint nth_error&amp;#039; (l:natlist) (n:nat) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil =&amp;gt; None&lt;br /&gt;
  | a :: l&amp;#039; =&amp;gt; if beq_nat n O&lt;br /&gt;
               then Some a&lt;br /&gt;
               else nth_error&amp;#039; l&amp;#039; (pred n)&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* Nota: Los condicionales funcionan sobre todo tipo inductivo con dos &lt;br /&gt;
   constructores en Coq, sin booleanos. *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      option_elim nat -&amp;gt; natoption -&amp;gt; nat&lt;br /&gt;
   tal que (option_elim d o) es el valor de o, si o tienve valor o es d&lt;br /&gt;
   en caso contrario.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition option_elim (d : nat) (o : natoption) : nat :=&lt;br /&gt;
  match o with&lt;br /&gt;
  | Some n&amp;#039; =&amp;gt; n&amp;#039;&lt;br /&gt;
  | None =&amp;gt; d&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 27. Definir la función&lt;br /&gt;
      hd_error : natlist -&amp;gt; natoption&lt;br /&gt;
   tal que (hd_error xs) es el primer elemento de xs, si xs es no vacía;&lt;br /&gt;
   o es None, en caso contrario. Por ejemplo,&lt;br /&gt;
      hd_error []    = None.&lt;br /&gt;
      hd_error [1]   = Some 1.&lt;br /&gt;
      hd_error [5;6] = Some 5.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition hd_error (l : natlist) : natoption :=&lt;br /&gt;
  match l with&lt;br /&gt;
  | nil   =&amp;gt; None&lt;br /&gt;
  | x::xs =&amp;gt; Some x&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
Example test_hd_error1 : hd_error [] = None.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error2 : hd_error [1] = Some 1.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
Example test_hd_error3 : hd_error [5;6] = Some 5.&lt;br /&gt;
Proof. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 28. Demostrar que&lt;br /&gt;
      hd default l = option_elim default (hd_error l).&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem option_elim_hd : forall (l:natlist) (default:nat),&lt;br /&gt;
  hd default l = option_elim default (hd_error l).&lt;br /&gt;
Proof.&lt;br /&gt;
  intros l default. destruct l as [|x xs].&lt;br /&gt;
  - reflexivity.&lt;br /&gt;
  - simpl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizar el módulo NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End NatList.&lt;br /&gt;
&lt;br /&gt;
(* =====================================================================&lt;br /&gt;
   § Funciones parciales (o diccionarios)&lt;br /&gt;
   ================================================================== *)&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo id con el constructor&lt;br /&gt;
      Id : nat -&amp;gt; id.&lt;br /&gt;
   La idea es usarlo como clave de los dicccionarios.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive id : Type :=&lt;br /&gt;
  | Id : nat -&amp;gt; id.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      beq_id : id -&amp;gt; id -&amp;gt; bool&lt;br /&gt;
   tal que  (beq_id x1 x2) se verifcia si tienen la misma clave.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition beq_id (x1 x2 : id) :=&lt;br /&gt;
  match x1, x2 with&lt;br /&gt;
  | Id n1, Id n2 =&amp;gt; beq_nat n1 n2&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 29. Demostrar que beq_id es reflexiva.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem beq_id_refl : forall x, true = beq_id x x.&lt;br /&gt;
Proof.&lt;br /&gt;
  intro x. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Iniciar el módulo PartialMap que importa a NatList.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Module PartialMap.&lt;br /&gt;
Export NatList.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir el tipo partial_map (para representar los&lt;br /&gt;
   diccionarios) con los contructores&lt;br /&gt;
      empty  : partial_map&lt;br /&gt;
      record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Inductive partial_map : Type :=&lt;br /&gt;
  | empty  : partial_map&lt;br /&gt;
  | record : id -&amp;gt; nat -&amp;gt; partial_map -&amp;gt; partial_map.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      update : partial_map -&amp;gt; id -&amp;gt; nat -&amp;gt; partial_map&lt;br /&gt;
   tal que (update d i v) es el diccionario obtenido a partir del d&lt;br /&gt;
   + si d tiene un elemento con clave i, le cambia su valor a v&lt;br /&gt;
   + en caso contrario, le añade el elemento v con clave i &lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Definition update (d : partial_map)&lt;br /&gt;
                  (x : id) (value : nat)&lt;br /&gt;
                  : partial_map :=&lt;br /&gt;
  record x value d.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejemplo. Definir la función&lt;br /&gt;
      find : id -&amp;gt; partial_map -&amp;gt; natoption &lt;br /&gt;
   tal que (find i d) es el valor de la entrada de d con clave i, o None&lt;br /&gt;
   si d no tiene ninguna entrada con clave i.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Fixpoint find (x : id) (d : partial_map) : natoption :=&lt;br /&gt;
  match d with&lt;br /&gt;
  | empty         =&amp;gt; None&lt;br /&gt;
  | record y v d&amp;#039; =&amp;gt; if beq_id x y&lt;br /&gt;
                     then Some v&lt;br /&gt;
                     else find x d&amp;#039;&lt;br /&gt;
  end.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 30. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
        find x (update d x v) = Some v.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_eq :&lt;br /&gt;
  forall (d : partial_map) (x : id) (v: nat),&lt;br /&gt;
    find x (update d x v) = Some v.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x v. destruct d as [|d&amp;#039; x&amp;#039; v&amp;#039;].&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
  - simpl. destruct x. simpl. rewrite &amp;lt;- beq_nat_refl. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 31. Demostrar que&lt;br /&gt;
      forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
        beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
Theorem update_neq :&lt;br /&gt;
  forall (d : partial_map) (x y : id) (o: nat),&lt;br /&gt;
    beq_id x y = false -&amp;gt; find x (update d y o) = find x d.&lt;br /&gt;
Proof.&lt;br /&gt;
  intros d x y o p. simpl. rewrite p. reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Nota. Finalizr el módulo PartialMap&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&lt;br /&gt;
End PartialMap.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 32. Se define el tipo baz por&lt;br /&gt;
      Inductive baz : Type :=&lt;br /&gt;
        | Baz1 : baz -&amp;gt; baz&lt;br /&gt;
        | Baz2 : baz -&amp;gt; bool -&amp;gt; baz.&lt;br /&gt;
   ¿Cuántos elementos tiene el tipo baz?&lt;br /&gt;
   ------------------------------------------------------------------ *)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jalonso</name></author>
		
	</entry>
</feed>