Acciones

Examen 2C sol

De Lógica matemática y fundamentos [Curso 2019-20]

theory examen_9_sep_sol
imports Main 
begin

lemma notnotI: "P ⟹ ¬¬ P"
  by auto

lemma mt: "⟦F ⟶ G; ¬G⟧ ⟹ ¬F"
by auto

text ------------------------------------------------------------------ 
  Ejercicio 1. (2.5 puntos) Demostrar detalladamente con Isabelle, 
  sin usar métodos automáticos (como simp, auto, ...) sino sólo las 
  reglas básicas, que el siguiente argumento es correcto:
  Ningún individuo que sea candidato será derrotado si hace una
  buena campaña. Todo individuo que se postula es un candidato. Cualquier
  candidato que no sea derrotado, será elegido. Todo individuo que sea
  elegido hace una buena campaña. Por tanto, todo individuo que se 
  postula será elegido si y sólo si hace una buena campaña. 

  Simbología: I(x): x es individuo, C(x): x es candidato,
              D(x): x es derrotado, B(x): x hace una buena campaña, 
              P(x): x se postula, E(x): x es elegido. 
---------------------------------------------------------------------
lemma 
  assumes "∀x. (I(x)∧C(x))∧B(x)⟶¬D(x)"
          "∀x. I(x)∧P(x) ⟶ C(x)"
          "∀x. C(x) ∧ ¬D(x) ⟶ E(x)"
          "∀x. I(x)∧E(x) ⟶ B(x)"
  shows   "∀x. I(x)∧P(x)⟶(E(x)⟷B(x))"
  proof (rule allI)
  fix a
  show "I(a)∧P(a) ⟶ (E(a)⟷B(a))"
    proof
      assume "I(a)∧P(a)"
      show "E(a)⟷B(a)"
        proof
          assume "E(a)"
          show  "B(a)"
             proof -
              have "I(a)" using I(a)P(a) by (rule conjunct1)
              then have 1:"I(a)∧E(a)" using E(a) by (rule conjI)
              have "I(a)∧E(a) ⟶ B(a)" using assms(4) by (rule allE)
              then show "B(a)" using 1 by (rule mp)
             qed  
        next
          assume "B(a)"
          show   "E(a)"
             proof -
              have "I(a)∧P(a) ⟶ C(a)" using assms(2) by (rule allE)
              then have "C(a)" using   I(a)P(a) by (rule mp)
              have "I(a)" using  I(a)P(a) by (rule conjunct1)
              then have "I(a)∧C(a)" using C(a) by (rule conjI)
              then have 2:"(I(a)∧C(a))∧B(a)" using B(a) 
                by (rule conjI)
              have "(I(a)∧C(a))∧B(a)⟶¬D(a)" using assms(1) 
                by (rule allE)
              then have "¬D(a)" using 2 by (rule mp)
              have 3:"C(a) ∧ ¬D(a) ⟶ E(a)" using assms(3) 
                by (rule allE)
              have "C(a)∧¬D(a)" using C(a) ‹¬D(a) by (rule conjI)
              with 3 show "E(a)" by (rule mp)
             qed
        qed
    qed
  qed              


text  -----------------------------------------------------------------
  Ejercicio 2. (2.5 puntos) Consideramos la función
     menores :: int  int list  bool
  tal que (menores a xs) es la lista de los elementos de la lista xs que 
  son menores que a. Por ejemplo,
     value "menores 2 [3,0,1] = [0,1]"
     value "menores 2 [3,0,5] = [0]"
-----------------------------------------------------------------------
 
fun menores :: "int ⇒ int list ⇒ int list" where
  "menores a []     = []"
| "menores a (x#xs) = (if x < a then x # (menores a xs)
                                else (menores a xs))"
 
value "menores 2 [3,0,1] = [0,1]"
value "menores 2 [3,0,5] = [0]"
 
text  -----------------------------------------------------------------
  Demostrar que la longitud de la lista de elementos menores que uno 
  dado es menor o igual que la longitud de la lista original.
-----------------------------------------------------------------------

 Demostración estructurada:

lemma menores_menor_1:
  "length (menores x xs) < Suc (length xs)"
proof(induct xs)
    show "length (menores x [])<Suc(length [])" by simp
  next
    fix xs a
    assume HI: "length (menores x xs) < Suc (length xs)"
    show "length (menores x (a#xs))< Suc(length (a#xs))"
    proof(cases "a<x")
      case True
      then have "length (menores x (a#xs)) = length(a#(menores x xs))" 
        by simp
      also have "... = Suc(length(menores x xs))" by simp
      also have "...< Suc(Suc( length  xs))" using HI by simp
      also have "... = Suc(length(a#xs))" by simp
      finally show ?thesis by simp
  next
    case False
    then have "length (menores x (a#xs)) = length(menores x xs)" by simp
    also have "... < Suc (length xs)" using HI by simp
    also have "... < Suc (length (a#xs))" by simp
    finally show ?thesis by simp
  qed
qed

 Demostración detallada:

lemma menores_menor_detallada:
  "length (menores x xs) < Suc (length xs)"
proof(induct xs)
  show "length (menores x []) < Suc (length [])" 
    by  (simp only: list.size lessI menores.simps(1))
next
  fix xs a
  assume HI: "length (menores x xs) < Suc (length xs)"
  show "length (menores x (a#xs))< Suc(length (a#xs))"
  proof (cases "a<x")
    case True
    then have "menores x (a#xs) = a#(menores x xs)" 
      by (simp only:if_True menores.simps)
    then have "length (menores x (a#xs)) = length(a#(menores x xs))" 
     by (simp only:)
    also have "... = Suc(length(menores x xs))" by (simp only:list.size)
    also have "...< Suc(Suc( length  xs))" using HI by (simp only:)
    also have "... = Suc(length(a#xs))" by (simp only: list.size)
    finally show ?thesis by this
  next
    case False
    then have "menores x (a#xs) = menores x xs" 
      by (simp only: if_False menores.simps(2))
    then have "length (menores x (a#xs)) = length(menores x xs)" 
      by (simp only:)
    also have "... < Suc (length xs)" using HI by (simp only:)
    also have "... < Suc (length (a#xs))" by (simp only: list.size)
    finally show ?thesis by this
  qed
qed

 Demostración aplicativa:

lemma menores_menor_aplicativa:
  "length (menores x xs) < Suc (length xs)"
  apply (induct xs)
   apply (simp only: list.size lessI menores.simps(1))
  apply (simp only:menores.simps(2))
  apply(split if_split)
  apply (rule conjI)
   apply (rule impI)
   apply (simp only: list.size)
  apply (rule impI)
  apply (simp only: list.size)
  done

 Demostración automática:

lemma menores_menor_auto:
  "length (menores x xs) < Suc (length xs)"
by (induct xs) auto


lemma 
  "length (menores x xs) < 1 + length xs"
proof(induct xs)
  show "length (menores x []) < 1 + (length [])" 
    by  (simp only: list.size lessI menores.simps(1))
next
  fix xs a
  assume HI: "length (menores x xs) < 1 + length xs"
  show "length (menores x (a#xs)) < 1 + length (a#xs)"
  proof (cases "a<x")
    case True
    then have "menores x (a#xs) = a#(menores x xs)" 
      by (simp only:if_True menores.simps)
    then have "length (menores x (a#xs)) = length(a#(menores x xs))" 
     by (simp only:)
    also have "... = 1 + (length(menores x xs))" by (simp only:list.size)
    also have "...< 1 + (1 + ( length  xs))" using HI by (simp only:)
    also have "... = 1 + (length(a#xs))" by (simp only: list.size)
    finally show ?thesis by this
  next
    case False
    then have "menores x (a#xs) = menores x xs" 
      by (simp only: if_False menores.simps(2))
    then have "length (menores x (a#xs)) = length(menores x xs)" 
      by (simp only:)
    also have "... < 1 +  (length xs)" using HI by (simp only:)
    also have "... < 1 +  (length (a#xs))" by (simp only: list.size)
    finally show ?thesis by this
  qed
qed

text ------------------------------------------------------------------
  Ejercicio 3. (2.5 puntos) Sea G un grupo. Demostrar que si se verifica
   x y. (((y^  x^)  y)  x = 𝟭), entonces también se verifica
   x. y. z. x  y = z  x  y = z

  Nota: No usar ninguno de los métodos automáticos: auto, blast, force,
  fast, arith o metis 
  ------------------------------------------------------------------ 

locale grupo =
  fixes prod :: "['a, 'a] ⇒ 'a" (infixl "⋅" 70)
    and neutro ("𝟭") 
    and inverso ("_^" [100] 100)
  assumes asociativa: "(x ⋅ y) ⋅ z = x ⋅ (y ⋅ z)"
      and neutro_i:   "𝟭 ⋅ x = x"
      and neutro_d:   "x ⋅ 𝟭 = x"
      and inverso_d:  "x ⋅ x^ = 𝟭"

(* Notas sobre notación:
   * El producto es ⋅ y se escribe con \ cdot (sin espacio entre ellos). 
   * El neutro es 𝟭 y se escribe con \ y one (sin espacio entre ellos).
   * El inverso de x es x^ y se escribe pulsando 2 veces en ^. *)

context grupo
begin

lemma
  assumes  "((y^ ⋅ x^) ⋅ y) ⋅ x = 𝟭"
  shows "x ⋅ y = z ⋅ x ⟶ y = z"
proof (rule impI)
  assume 1: "x ⋅ y = z ⋅ x"
  show "y = z"
  proof-
    have  2: "x ⋅ y = y ⋅ x"
    proof-
      have "x ⋅ y = (x ⋅ y) ⋅ 𝟭" by (simp only:  neutro_d)
      also have "… =  (x ⋅ y) ⋅ (((y^ ⋅ x^) ⋅ y) ⋅ x)" 
        using assms by (simp only:)
      also have "… =  (x ⋅ (y ⋅ y^) ⋅ x^) ⋅ y ⋅ x"
        by (simp only: asociativa)
      also have "… =  (x ⋅ 𝟭 ⋅ x^) ⋅ y ⋅ x"
        by (simp only: inverso_d)
      also have "… =  (x ⋅ x^) ⋅ y ⋅ x"
        by (simp only: neutro_d)
      also have "… = 𝟭 ⋅ y ⋅ x"
        by (simp only: inverso_d)
      also have "… = y ⋅ x"
         by (simp only: neutro_i)
       finally show  "x ⋅ y = y ⋅ x" 
         by this
     qed
     have "y ⋅ x = z ⋅ x" using 1 2 by (simp only:)
     then have "(y ⋅ x) ⋅ x^ = (z ⋅ x) ⋅ x^" by (simp only:)
     then have "y ⋅ (x ⋅ x^) = z ⋅ (x ⋅ x^)" by (simp only:asociativa)
     then have "y ⋅ 𝟭 = z ⋅ 𝟭" by (simp only:inverso_d)
     then show "y = z " by (simp only:neutro_d)
    qed
qed

end

text -----------------------------------------------------------------
 Ejercicio 4. (2.5 puntos) El conjunto de los conjuntos finitos 
 se define inductivamente por
    inductive_set Finito :: "'a set set"
      where
        vacioI:   "{} ∈ Finito" |
        insertaI: "A ∈ Finito ⟹ insert a A ∈ Finito"

 Demostrar detalladamente que la unión de dos conjuntos finitos es 
 finito; es decir.
      A  Finito; B  Finito   A  B  Finito

 Nota: Los únicos métodos que se pueden usar son induct y 
 (simp only: ...).  
 ---------------------------------------------------------------------

inductive_set Finito :: "'a set set"
  where
    vacioI:   "{} ∈ Finito" |
    insertaI: "A ∈ Finito ⟹ insert a A ∈ Finito"

  Demostración declarativa  detallada 
lemma "⟦ A ∈ Finito; B ∈ Finito ⟧ ⟹ A ∪ B ∈ Finito"
proof (induct rule: Finito.induct)
  assume "B ∈ Finito"
  then show "{} ∪ B ∈ Finito" by (simp only: Un_empty_left)
next
  fix A a
  assume AF: "A ∈ Finito" and
         HI: "B ∈ Finito ⟹ A ∪ B ∈ Finito" and
         BF: "B ∈ Finito"
  have "A ∪ B ∈ Finito" by (simp only: HI BF)
  then have "insert a (A ∪ B) ∈ Finito" by (simp only: insertaI)
  then show "(insert a A) ∪ B ∈ Finito" 
    by (simp only: Set.Un_insert_left)
qed

  Demostración estructurada 
lemma "⟦ A ∈ Finito; B ∈ Finito ⟧ ⟹ A ∪ B ∈ Finito"
proof (induct rule: Finito.induct)
  assume "B ∈ Finito"
  then show "{} ∪ B ∈ Finito" by simp
next
  fix A a
  assume "A ∈ Finito" 
         "B ∈ Finito ⟹ A ∪ B ∈ Finito" 
         "B ∈ Finito"
  then have "A ∪ B ∈ Finito" by simp
  then show "(insert a A) ∪ B ∈ Finito" by (simp add: insertaI)
qed

  Demostración aplicativa  detallada 
lemma "⟦ A ∈ Finito; B ∈ Finito ⟧ ⟹ A ∪ B ∈ Finito"
  apply (erule Finito.induct)
   apply (simp only: Un_empty_left)
  apply (simp only: Set.Un_insert_left)
  apply (simp only: insertaI)
  done

  Demostración aplicativa estructurada 
lemma "⟦ A ∈ Finito; B ∈ Finito ⟧ ⟹ A ∪ B ∈ Finito"
  apply (erule Finito.induct)
   apply simp 
  apply (auto intro: insertaI)
  done

  Demostración automática 
lemma "⟦ A ∈ Finito; B ∈ Finito ⟧ ⟹ A ∪ B ∈ Finito"
  by (induct rule: Finito.induct)
     (auto intro: insertaI)

end