<?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=Alerodrod5</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=Alerodrod5"/>
	<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php/Especial:Contribuciones/Alerodrod5"/>
	<updated>2026-07-18T11:16:24Z</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=115</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=115"/>
		<updated>2018-05-09T15:55:26Z</updated>

		<summary type="html">&lt;p&gt;Alerodrod5: &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;
(* 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;
  (* 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>Alerodrod5</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_5&amp;diff=114</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=114"/>
		<updated>2018-05-09T15:50:52Z</updated>

		<summary type="html">&lt;p&gt;Alerodrod5: &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;
(* 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;
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>Alerodrod5</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=71</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=71"/>
		<updated>2018-03-23T15:09:16Z</updated>

		<summary type="html">&lt;p&gt;Alerodrod5: &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;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity. 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. Qed.&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;
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:&lt;br /&gt;
  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>Alerodrod5</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Tema_3&amp;diff=70</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=70"/>
		<updated>2018-03-23T15:07:45Z</updated>

		<summary type="html">&lt;p&gt;Alerodrod5: &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;
Proof.&lt;br /&gt;
  intro p. destruct p as [n m]. simpl. reflexivity. 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. Qed.&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;
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>Alerodrod5</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Relaci%C3%B3n_1&amp;diff=31</id>
		<title>Relación 1</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Relaci%C3%B3n_1&amp;diff=31"/>
		<updated>2018-02-25T15:09:53Z</updated>

		<summary type="html">&lt;p&gt;Alerodrod5: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* Relación 1: Programación funcional en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export Basics.&lt;br /&gt;
&lt;br /&gt;
Definition admit {T: Type} : T.  Admitted.&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;
-- 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;
&lt;br /&gt;
Example prop_nandb2: (nandb false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
&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;
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;
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;
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.1. 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;
-- alerodrod5&lt;br /&gt;
Definition andb3 (x:bool) (y:bool) (z: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;
&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;
&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;
   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;
(* 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;
&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;
   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;
Example prop_blt_nat1: (blt_nat 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example prop_blt_nat2: (blt_nat 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&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;
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;
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;
   Ejercicio 5. Demostrar que&lt;br /&gt;
      forall n m o : nat,&lt;br /&gt;
         n = m -&amp;gt; m = o -&amp;gt; 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 . intros o Ho. rewrite -&amp;gt; Ho . intros H. rewrite -&amp;gt; H. reflexivity. 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. rewrite -&amp;gt; H1. rewrite -&amp;gt; H2. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar que&lt;br /&gt;
      forall n m : nat,&lt;br /&gt;
        m = S n -&amp;gt;&lt;br /&gt;
        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. intros H. rewrite -&amp;gt; H. reflexivity. 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. rewrite H. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que&lt;br /&gt;
      forall b c : bool,&lt;br /&gt;
        andb b c = true -&amp;gt; c = true.&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;
    + 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;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Dmostrar que&lt;br /&gt;
      forall n : nat,&lt;br /&gt;
        beq_nat 0 (n + 1) = false.&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. Qed.&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. rewrite x. rewrite x. reflexivity. 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;
 &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>Alerodrod5</name></author>
		
	</entry>
	<entry>
		<id>https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Relaci%C3%B3n_1&amp;diff=17</id>
		<title>Relación 1</title>
		<link rel="alternate" type="text/html" href="https://www.glc.us.es/~jalonso/SLC2018/index.php?title=Relaci%C3%B3n_1&amp;diff=17"/>
		<updated>2018-02-24T15:39:26Z</updated>

		<summary type="html">&lt;p&gt;Alerodrod5: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;source lang=&amp;quot;ocaml&amp;quot;&amp;gt;&lt;br /&gt;
(* Relación 1: Programación funcional en Coq *)&lt;br /&gt;
&lt;br /&gt;
Require Export Basics.&lt;br /&gt;
&lt;br /&gt;
Definition admit {T: Type} : T.  Admitted.&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;
-- 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;
&lt;br /&gt;
Example prop_nandb2: (nandb false false) = true.&lt;br /&gt;
Proof. simpl. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
&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;
   Ejercicio 2.1. 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;
-- alerodrod5&lt;br /&gt;
Definition andb3 (x:bool) (y:bool) (z: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;
&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;
   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;
-- alerodrod5&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;
&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;
   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;
Example prop_blt_nat1: (blt_nat 2 2) = false.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&lt;br /&gt;
Example prop_blt_nat2: (blt_nat 2 4) = true.&lt;br /&gt;
Proof. simpl. reflexivity.  Qed.&lt;br /&gt;
&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;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 5. Demostrar que&lt;br /&gt;
      forall n m o : nat,&lt;br /&gt;
         n = m -&amp;gt; m = o -&amp;gt; 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 . intros o Ho. rewrite -&amp;gt; Ho . intros H. rewrite -&amp;gt; H. reflexivity. Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 6. Demostrar que&lt;br /&gt;
      forall n m : nat,&lt;br /&gt;
        m = S n -&amp;gt;&lt;br /&gt;
        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. intros H. rewrite -&amp;gt; H. reflexivity. Qed. &lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 7. Demostrar que&lt;br /&gt;
      forall b c : bool,&lt;br /&gt;
        andb b c = true -&amp;gt; c = true.&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;
    + reflexivity.&lt;br /&gt;
Qed.&lt;br /&gt;
&lt;br /&gt;
(* ---------------------------------------------------------------------&lt;br /&gt;
   Ejercicio 8. Dmostrar que&lt;br /&gt;
      forall n : nat,&lt;br /&gt;
        beq_nat 0 (n + 1) = false.&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;
(* ---------------------------------------------------------------------&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;
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;
Admitted.&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;
Theorem andb_eq_orb :&lt;br /&gt;
  forall (b c : bool),&lt;br /&gt;
    (andb b c = orb b c) -&amp;gt; b = c.&lt;br /&gt;
Admitted.&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;
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;
  admit.&lt;br /&gt;
&lt;br /&gt;
Example prop_nat2Anat1: (nat2Anat (SD (SD C))) = 3.&lt;br /&gt;
Admitted.&lt;br /&gt;
&lt;br /&gt;
Example prop_nat2Anat2: (nat2Anat (D (SD (SD C)))) = 6.&lt;br /&gt;
Admitted.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alerodrod5</name></author>
		
	</entry>
</feed>