Acciones

T4 sol

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

theory T4_sol
imports Main 
begin

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

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

text -----------------------------------------------------------------
  Se define la función
     elimina :: nat  'a list  'a list
  tal que (elimina n xs) es la lista obtenida eliminando los n primeros
  elementos de xs. Por ejemplo, 
     elimina 2 [a,c,d,b,e] = [d,b,e]
  ---------------------------------------------------------------------

fun elimina :: "nat ⇒ 'a list ⇒ 'a list" where
  "elimina n []           = []"
| "elimina 0 xs           = xs"
| "elimina (Suc n) (x#xs) = elimina n xs"

text ------------------------------------------------------------------
  Ejercicio. Demostrar que 
     length (elimina n xs)  length xs - n
  ---------------------------------------------------------------------

 Por inducción en n y xs según el esquema elimina.induct

 Estructurada
lemma  "length (elimina n xs) ≤ length xs"
proof(induct n xs rule :elimina.induct)
  show "⋀n. length (elimina n []) ≤ length []" by simp
  next
  show "⋀v va. length (elimina 0 (v # va)) ≤ length (v # va)"
  by simp
  next
  show "⋀n x xs.
       length (elimina n xs) ≤ length xs ⟹
       length (elimina (Suc n) (x # xs)) ≤ length (x # xs)"
       by simp
 qed

 Automática
lemma  "length (elimina n xs) ≤ length xs"
  by (induct n xs rule :elimina.induct) simp_all

 Declarativa detallada

lemma  "length (elimina n xs) ≤ length xs"
proof(induct n xs rule :elimina.induct)
  fix n ::"nat"
  show "length (elimina n []) ≤ length []" 
    by (simp only: elimina.simps(1) list.size(3))
next
  fix x::"'a" and xs::"'a list"
  show "length (elimina 0 (x # xs)) ≤ length (x #xs)"
    by (simp only: elimina.simps(2) list.size(2))
next
  fix n ::"nat" and x::"'a" and xs::"'a list"
  assume H:"length (elimina n xs) ≤ length xs"
  have "length(elimina (Suc n) (x#xs)) = length(elimina n xs)"
    by (simp only: elimina.simps(3))
  also have "… ≤ length xs"
    using H by (simp only:)
  also have "… ≤ length (x#xs)"
    by (simp only: list.size(4))
  finally show "length(elimina (Suc n) (x#xs)) ≤ length (x#xs)".
  qed

 Aplicativa detallada

lemma  "length (elimina n xs) ≤ length xs"
  apply (induct n xs rule :elimina.induct)
  apply (simp only: elimina.simps(1))
  apply (simp only: elimina.simps(2))
  apply (simp only: elimina.simps(3))
  apply (simp only: list.size)
  done


 Por inducción en n con xs arbitrario  

 Auxiliar
lemma elimina0: "elimina 0 xs = xs"
  apply (cases xs) 
  apply (simp only: elimina.simps(1))
  apply (simp only: elimina.simps(2))
  done

 Estructurada  
lemma "length (elimina n xs) ≤ length xs - n"
proof (induct n arbitrary: xs)
   show "⋀xs. length (elimina 0 xs) ≤ length xs - 0" 
   by (simp only: elimina0)
   next 
    fix n :: nat and xs :: "'a list"
  assume HI: "⋀xs:: 'a list. length (elimina n xs) ≤ length xs - n" 
  show "length (elimina (Suc n) xs) ≤ length xs - (Suc n)"
  proof (cases xs)
  case Nil
  then show ?thesis by simp
  next
  case (Cons a list)
  then show ?thesis using HI by simp
  qed
 qed 

  
 Declarativa detallada
lemma "length (elimina n xs) ≤ length xs - n"
proof (induct n arbitrary: xs)
  fix xs :: "'a list"
  show "length (elimina 0 xs) ≤ length xs - 0" 
    by (simp only: elimina0 list.size(3))
next
  fix n :: nat and xs :: "'a list"
  assume HI: "⋀xs:: 'a list. length (elimina n xs) ≤ length xs - n" 
  show "length (elimina (Suc n) xs) ≤ length xs - (Suc n)"
  proof (cases xs)
    assume "xs = []" 
    then have "elimina (Suc n) xs = elimina (Suc n) []"
      by (rule arg_cong)
    also have "… = []" 
      by (simp only: elimina.simps(1))
    finally have "elimina (Suc n) xs = []" 
      by this
    then have "length (elimina (Suc n) xs) = 0" 
      by (simp only: list.size(3)) 
    then show "length (elimina (Suc n) xs) ≤ length xs - (Suc n)" 
      by (simp only: list.size(3))
  next
    fix y:: "'a" and  ys :: "'a list"
    assume 1: "xs = y # ys"
    have 2: "length (elimina n ys) ≤ length ys - n"
      using HI by this
    have "length (elimina (Suc n) xs) = length (elimina (Suc n) (y#ys))" 
      using 1 by (rule arg_cong)
    also have "… = length (elimina n ys)" 
      by (simp only: elimina.simps(3))
    also have "… ≤  length ys - n" 
      using 2 by (simp only:)
    also have "… = 1 + length ys - (Suc n)" 
      by (simp only: diff_Suc_Suc)
    also have "… = length (y#ys) - (Suc n)" 
      by (simp only: list.size(4))
    also have "… = length xs - (Suc n)" 
      using 1 by (simp only: list.size(4))
    finally show "length (elimina (Suc n) xs) ≤ length xs - (Suc n)" 
      by this    
  qed
qed

 Aplicativa detallada

lemma "length (elimina n xs) ≤ length xs - n"
  apply (induct n arbitrary: xs)
   apply (simp only: elimina0)
  apply (case_tac xs)
   apply (simp only: elimina.simps)
   apply (simp only: list.size(3))
  apply (simp only: elimina.simps(3))
  apply (simp only: list.size(4))
  apply (simp only: add_Suc_right)
  apply (simp only: add.right_neutral)
  apply (simp only: diff_Suc_Suc)
  done

 Demostración por inducción en xs con n arbitrario

 Estructurada

lemma  "length (elimina n xs) ≤ length xs"
proof (induct xs arbitrary: n)
  show "⋀n. length (elimina n []) ≤ length []" by simp
  next
  fix n::"nat" and x::'a and xs:: "'a list"
  assume HI: "  ⋀n. length (elimina n xs) ≤ length xs"
  show "length (elimina n (x# xs)) ≤ length (x#xs)"
  proof(cases n)
  case 0
  then show ?thesis by simp
  next
  case (Suc nat)
  then show ?thesis using HI
  by (metis elimina.simps(3) list.size(4) trans_le_add1)
  qed
  qed

 Declarativa detallada

lemma  "length (elimina n xs) ≤ length xs"
proof (induct xs arbitrary: n)
  fix n::"nat"
  show "length (elimina n []) ≤ length []" 
     by (simp only: elimina.simps(1) list.size)
next
  fix n::"nat" and x::'a and xs:: "'a list"
  assume HI: "  ⋀n. length (elimina n xs) ≤ length xs"
  show "length (elimina n (x# xs)) ≤ length (x#xs)"
  proof(cases n)
    assume "n=0"
    then have "(elimina n (x# xs)) =(x#xs)" 
      by (simp only: elimina.simps(2))
      then have "length (elimina n (x# xs)) = length (x#xs)"  
        by (rule arg_cong)
        then show  "length (elimina n (x# xs)) ≤ length (x#xs)" 
          by (simp only: order_refl)
  next
    fix m:: nat
    assume "n=(Suc m)"
    then have "length (elimina n (x# xs)) = 
               length (elimina (Suc m) (x# xs))" 
                by (rule arg_cong)
    also have "… =length (elimina m xs)" 
                by (simp only: elimina.simps(3))
    also have "… ≤ length xs" using HI by (simp only:)
    also have "… ≤ 1+length xs " by (simp only: le_add1)
    also have "…≤ length (x#xs)" by (simp only: list.size)
    finally show "length (elimina n (x# xs))≤length (x#xs)" 
      by (simp only:)
  qed
  qed  
 
 Aplicativa detallada

lemma "length (elimina n xs) ≤ length xs - n"
  apply (induct xs arbitrary: n)
  apply (simp only: elimina.simps(1) list.size)
  apply (case_tac n)
  apply (simp only: elimina.simps(2) list.size)
  apply (simp only: elimina.simps(3) list.size)
  apply (simp only:add_Suc_right)
  apply (simp only:add.right_neutral)
  apply (simp only: diff_Suc_Suc)
  done


  
text ------------------------------------------------------------------ 
  Ejercicio 2. Demostrar que si se verifica 
     x. (P x  (y. Q y))
  entonces se verifica 
     x. y. (P x  Q y)

  Nota: Hacer la demostración de forma detallada. Es opcional hacerla 
  de forma declarativa o aplicativa.
  --------------------------------------------------------------------

 Demostración declarativa detallada
  
lemma 
    fixes P Q :: "'b ⇒ bool" 
    assumes "∀x. ∃y. (P x ⟶ Q y)"
    shows   "∀x. (P x ⟶ (∃y. Q y))"
proof (rule allI)
  fix x
  show "P x ⟶ (∃y. Q y)"
  proof (rule impI)
    assume "P x"
    have " ∃y. (P x ⟶ Q y)" 
      using assms by (rule allE)
    then obtain b where "P x ⟶ Q b" 
      by (rule exE)
    then have "Q b" 
      using P x by (rule mp)
    then show "∃y. Q y" 
      by (rule exI) 
  qed
qed

 Demostración aplicativa detallada

lemma 
 "∀x. (P x ⟶ (∃y. Q y)) ⟹ ∀x. ∃y. (P x ⟶ Q y)"
  apply(rule allI)
  apply(erule_tac x = x in allE)
  apply(case_tac "P x")
  apply(drule mp, assumption)
  apply(erule exE)
  apply (rule_tac x = y in exI)
  apply(rule impI, assumption)
  apply (rule exI)
  apply(rule impI)
  apply(erule notE, assumption)
  done

end