Acciones

Diferencia entre revisiones de «Relación 8»

De Razonamiento automático (2018-19)

Línea 2: Línea 2:
 
chapter {* R8: Gramáticas libres de contexto *}
 
chapter {* R8: Gramáticas libres de contexto *}
  
theory R8_Gramaticas_libre_de_contexto
+
theory R8_Gramaticas_libre_de_contexto_alu
 
imports Main
 
imports Main
 
begin
 
begin
Línea 66: Línea 66:
 
(* cammonagu *)
 
(* cammonagu *)
 
declare S1 [iff] S2[intro!,simp]
 
declare S1 [iff] S2[intro!,simp]
 +
 
(* cammonagu *)
 
(* cammonagu *)
 
declare T1 [iff]
 
declare T1 [iff]
 +
 
(* cammonagu *)
 
(* cammonagu *)
 
lemma T2ImpS: "w ∈ T ⟹ w ∈ S"
 
lemma T2ImpS: "w ∈ T ⟹ w ∈ S"
Línea 83: Línea 85:
 
   thus ?thesis using assms .
 
   thus ?thesis using assms .
 
qed
 
qed
 
  
 
text {*   
 
text {*   
Línea 107: Línea 108:
 
   moreover assume "w ∈ T"
 
   moreover assume "w ∈ T"
 
   moreover have "⟦v ∈ T; w ∈ T⟧ ⟹ v @ w ∈ T" for v w
 
   moreover have "⟦v ∈ T; w ∈ T⟧ ⟹ v @ w ∈ T" for v w
   proof (induction "length w + length v" arbitrary: w v rule: less_induct)
+
   proof (induction "length w + length v"  
 +
        arbitrary: w v  
 +
        rule: less_induct)
 
     case IH: less
 
     case IH: less
  
Línea 122: Línea 125:
 
       hence 1: "v @ w = v @ w1 @ [A] @ w2 @ [B]" by simp
 
       hence 1: "v @ w = v @ w1 @ [A] @ w2 @ [B]" by simp
  
       have "length w1 < length w" using `w = w1 @ [A] @ w2 @ [B]` by simp
+
       have "length w1 < length w" using `w = w1 @ [A] @ w2 @ [B]`  
 +
        by simp
 
       hence "length v + length w1 < length v + length w" by simp
 
       hence "length v + length w1 < length v + length w" by simp
 
       moreover note `v ∈ T`
 
       moreover note `v ∈ T`
Línea 150: Línea 154:
 
   show "w ∈ T ⟹ v @ w ∈ T"
 
   show "w ∈ T ⟹ v @ w ∈ T"
 
   proof (induction rule: T.induct)
 
   proof (induction rule: T.induct)
     show "v @ [] ∈ T" using `v ∈ T` by (simp only: List.append.right_neutral)
+
     show "v @ [] ∈ T" using `v ∈ T`  
 +
      by (simp only: List.append.right_neutral)
 
   next
 
   next
 
     fix va w
 
     fix va w
     have "v @ va ∈ T ⟹ w ∈ T ⟹ (v @ va) @ [A] @ w @ [B] ∈ T " by (rule T2)
+
     have "v @ va ∈ T ⟹ w ∈ T ⟹ (v @ va) @ [A] @ w @ [B] ∈ T "  
     then show "v @ va ∈ T ⟹ w ∈ T ⟹ v @ va @ [A] @ w @ [B] ∈ T " by (simp only: List.append_assoc)
+
      by (rule T2)
 +
     then show "v @ va ∈ T ⟹ w ∈ T ⟹ v @ va @ [A] @ w @ [B] ∈ T "  
 +
      by (simp only: List.append_assoc)
 
   qed
 
   qed
 
qed
 
qed
Línea 218: Línea 225:
  
 
(* benber *)
 
(* benber *)
lemma balanceada_correcto_aux1: "balanceada_aux w n ⟹ balanceada_aux (w @ [B]) (Suc n)"
+
lemma balanceada_correcto_aux1:  
 +
  "balanceada_aux w n ⟹ balanceada_aux (w @ [B]) (Suc n)"
 
proof (induction w arbitrary: n)
 
proof (induction w arbitrary: n)
 
   case Nil
 
   case Nil
Línea 306: Línea 314:
 
   assume "balanceada w"
 
   assume "balanceada w"
 
   hence "balanceada_aux w 0" by simp
 
   hence "balanceada_aux w 0" by simp
   hence "balanceada_aux (w@[B]) 1" using balanceada_correcto_aux1 by simp
+
   hence "balanceada_aux (w@[B]) 1" using balanceada_correcto_aux1  
 +
    by simp
 
   hence "balanceada_aux ([A] @ w @ [B]) 0" by simp
 
   hence "balanceada_aux ([A] @ w @ [B]) 0" by simp
 
   thus "balanceada ([A] @ w @ [B])" by simp
 
   thus "balanceada ([A] @ w @ [B])" by simp
Línea 316: Línea 325:
 
(* alfmarcua antramhur *)
 
(* alfmarcua antramhur *)
 
lemma balanceada_correcto_aux3:
 
lemma balanceada_correcto_aux3:
   shows "balanceada_aux v m ⟹ balanceada_aux w n ⟹ balanceada_aux (v @ w) (m+n)"
+
   shows "balanceada_aux v m ⟹  
 +
        balanceada_aux w n ⟹  
 +
        balanceada_aux (v @ w) (m+n)"
 
proof (induction v arbitrary: n m)
 
proof (induction v arbitrary: n m)
 
   case Nil
 
   case Nil
Línea 322: Línea 333:
 
   proof (cases m)
 
   proof (cases m)
 
     case 0
 
     case 0
     then have "balanceada_aux w (m + n)" using Nil.prems(2) by (simp only:Groups.monoid_add_class.add.left_neutral)
+
     then have "balanceada_aux w (m + n)" using Nil.prems(2)  
 +
      by (simp only:Groups.monoid_add_class.add.left_neutral)
 
     then show ?thesis  by (simp only:List.append.append_Nil)
 
     then show ?thesis  by (simp only:List.append.append_Nil)
 
   next
 
   next
 
     case (Suc mm)
 
     case (Suc mm)
     then have "False" using Nil.prems(1) by (simp only: balanceada_aux.simps(2))
+
     then have "False" using Nil.prems(1)  
 +
      by (simp only: balanceada_aux.simps(2))
 
     then show ?thesis ..
 
     then show ?thesis ..
 
   qed
 
   qed
Línea 335: Línea 348:
 
     define k :: nat where "k = m + 1"
 
     define k :: nat where "k = m + 1"
 
     case A
 
     case A
     then have "balanceada_aux v k" using `k = m + 1` IS.prems(1) by simp
+
     then have "balanceada_aux v k" using `k = m + 1` IS.prems(1)  
     then have "balanceada_aux (v @ w) (k + n)" using IS.prems(2)  by (rule IS.IH)
+
      by simp
     then have "balanceada_aux (v @ w) (Suc(m + n))" using `k = m + 1` by simp
+
     then have "balanceada_aux (v @ w) (k + n)" using IS.prems(2)   
     then have "balanceada_aux (A # (v @ w)) (m + n)" by (simp only: balanceada_aux.simps(5))
+
      by (rule IS.IH)
     then show ?thesis using `a = A` by (simp only:List.append.append_Cons)
+
     then have "balanceada_aux (v @ w) (Suc(m + n))" using `k = m + 1`  
 +
      by simp
 +
     then have "balanceada_aux (A # (v @ w)) (m + n)"  
 +
      by (simp only: balanceada_aux.simps(5))
 +
     then show ?thesis using `a = A`  
 +
      by (simp only:List.append.append_Cons)
 
   next
 
   next
 
     case B
 
     case B
Línea 345: Línea 363:
 
     proof (cases m)
 
     proof (cases m)
 
       case 0
 
       case 0
       then have "False" using IS.prems(1) `a = B` by (simp only: balanceada_aux.simps(3))
+
       then have "False" using IS.prems(1) `a = B`  
 +
        by (simp only: balanceada_aux.simps(3))
 
       then show ?thesis ..
 
       then show ?thesis ..
 
     next
 
     next
 
       case (Suc mm)
 
       case (Suc mm)
       hence "balanceada_aux v mm" using IS.prems(1) `a = B` by (simp only: balanceada_aux.simps(4))
+
       hence "balanceada_aux v mm" using IS.prems(1) `a = B`  
       then have "balanceada_aux (v @ w) (mm + n)" using IS.prems(2) by (rule IS.IH)
+
        by (simp only: balanceada_aux.simps(4))
       then have "balanceada_aux (B # (v @ w)) (Suc (mm + n))" by (simp only: balanceada_aux.simps(4))
+
       then have "balanceada_aux (v @ w) (mm + n)" using IS.prems(2)  
       then have "balanceada_aux (B # (v @ w)) (m + n)" using `m = Suc mm` by (simp only: Nat.plus_nat.add_Suc)
+
        by (rule IS.IH)
       then show ?thesis using `a=B`  by (simp only:List.append.append_Cons)
+
       then have "balanceada_aux (B # (v @ w)) (Suc (mm + n))"  
 +
        by (simp only: balanceada_aux.simps(4))
 +
       then have "balanceada_aux (B # (v @ w)) (m + n)"  
 +
        using `m = Suc mm` by (simp only: Nat.plus_nat.add_Suc)
 +
       then show ?thesis using `a=B`   
 +
        by (simp only:List.append.append_Cons)
 
     qed
 
     qed
 
   qed
 
   qed
Línea 368: Línea 392:
 
   then have 1:"balanceada_aux w 0" by (simp only: balanceada.simps)
 
   then have 1:"balanceada_aux w 0" by (simp only: balanceada.simps)
 
   have "balanceada_aux [] 0" by (simp only: balanceada_aux.simps(1))
 
   have "balanceada_aux [] 0" by (simp only: balanceada_aux.simps(1))
   then have 2:"balanceada_aux (B#[]) (Suc 0)" by (simp only: balanceada_aux.simps(4))
+
   then have 2:"balanceada_aux (B#[]) (Suc 0)"  
   have "balanceada_aux w 0 ⟹ balanceada_aux [B] (Suc 0) ⟹  balanceada_aux (w @ [B]) (0+Suc 0)" by (rule balanceada_correcto_aux3)
+
    by (simp only: balanceada_aux.simps(4))
   then have "balanceada_aux (w @ [B]) (Suc 0)" using 1 2 by (simp only:Groups.monoid_add_class.add.left_neutral)
+
   have "balanceada_aux w 0 ⟹  
   then have "balanceada_aux (A # (w @ [B])) 0" by (simp only: balanceada_aux.simps(5))
+
        balanceada_aux [B] (Suc 0) ⟹   
   then have "balanceada_aux ([A] @ w @ [B]) 0" by (simp only: List.append_Cons List.append_Nil)
+
        balanceada_aux (w @ [B]) (0+Suc 0)"  
 +
    by (rule balanceada_correcto_aux3)
 +
   then have "balanceada_aux (w @ [B]) (Suc 0)" using 1 2  
 +
    by (simp only:Groups.monoid_add_class.add.left_neutral)
 +
   then have "balanceada_aux (A # (w @ [B])) 0"  
 +
    by (simp only: balanceada_aux.simps(5))
 +
   then have "balanceada_aux ([A] @ w @ [B]) 0"  
 +
    by (simp only: List.append_Cons List.append_Nil)
 
   then show ?case by (simp only: balanceada.simps)
 
   then show ?case by (simp only: balanceada.simps)
 
next
 
next
 
   case (S3 v w)
 
   case (S3 v w)
 
   then have 1:"balanceada_aux w 0" by (simp only: balanceada.simps)
 
   then have 1:"balanceada_aux w 0" by (simp only: balanceada.simps)
   have 2:"balanceada_aux v 0" using S3(3) by (simp only: balanceada.simps)
+
   have 2:"balanceada_aux v 0" using S3(3)  
   have "balanceada_aux v 0 ⟹ balanceada_aux w 0 ⟹  balanceada_aux (v @ w) (0+0)" by (rule balanceada_correcto_aux3)
+
    by (simp only: balanceada.simps)
   then have "balanceada_aux (v @ w) 0" using 1 2 by (simp only:Groups.monoid_add_class.add.right_neutral)
+
   have "balanceada_aux v 0 ⟹  
 +
        balanceada_aux w 0 ⟹   
 +
        balanceada_aux (v @ w) (0+0)"  
 +
    by (rule balanceada_correcto_aux3)
 +
   then have "balanceada_aux (v @ w) 0" using 1 2  
 +
    by (simp only:Groups.monoid_add_class.add.right_neutral)
 
   then show ?case by (simp only: balanceada.simps)
 
   then show ?case by (simp only: balanceada.simps)
 
qed
 
qed
Línea 391: Línea 427:
  
 
(* benber *)
 
(* benber *)
lemma balanceada_aux_unico: "⟦balanceada_aux w k; balanceada_aux w l⟧ ⟹ k = l" for w k l
+
lemma balanceada_aux_unico:  
 +
  "⟦balanceada_aux w k; balanceada_aux w l⟧ ⟹ k = l" for w k l
 
proof (induction w arbitrary: k l)
 
proof (induction w arbitrary: k l)
 
   case Nil
 
   case Nil
Línea 421: Línea 458:
 
         case (Suc l')
 
         case (Suc l')
 
         hence "balanceada_aux w' l'" using IS.prems `x = B` by simp
 
         hence "balanceada_aux w' l'" using IS.prems `x = B` by simp
         thus ?thesis using `balanceada_aux w' k'` IS.IH `k = Suc k'` `l = Suc l'` by auto
+
         thus ?thesis  
 +
          using `balanceada_aux w' k'` IS.IH `k = Suc k'` `l = Suc l'`  
 +
          by auto
 
       qed
 
       qed
 
     qed
 
     qed
Línea 428: Línea 467:
  
 
lemma balanceada_completo_aux1:
 
lemma balanceada_completo_aux1:
   "⟦balanceada (x # w @ [y]); ⋀u v. u ≠ [] ∧ v ≠ [] ∧ u @ v = x # w @ [y] ⟶ ¬ (balanceada v)⟧
+
   "⟦balanceada (x # w @ [y]);  
 +
    ⋀u v. u ≠ [] ∧ v ≠ [] ∧ u @ v = x # w @ [y] ⟶ ¬ (balanceada v)⟧
 
     ⟹ x = A ∧ y = B ∧ balanceada w"
 
     ⟹ x = A ∧ y = B ∧ balanceada w"
 
proof -
 
proof -
Línea 434: Línea 474:
 
   hence bal: "balanceada_aux ( x # w @ [y] ) 0" by simp
 
   hence bal: "balanceada_aux ( x # w @ [y] ) 0" by simp
  
   assume postfix_con: "⋀u v. u ≠ [] ∧ v ≠ [] ∧ u @ v = x # w @ [y] ⟶ ¬ (balanceada v)"
+
   assume postfix_con: "⋀u v. u ≠ [] ∧ v ≠ [] ∧ u @ v = x # w @ [y] ⟶  
 +
                            ¬ (balanceada v)"
  
 
   have "x = A"
 
   have "x = A"
Línea 455: Línea 496:
 
     case IS: (Cons x w)
 
     case IS: (Cons x w)
 
     hence "balanceada_aux (x # w @ [y]) n" by simp
 
     hence "balanceada_aux (x # w @ [y]) n" by simp
     hence "∃m. balanceada_aux (w @ [y]) m" using balanceada_aux.elims(2) by blast (* SH'd *)
+
     hence "∃m. balanceada_aux (w @ [y]) m" using balanceada_aux.elims(2)  
 +
      by blast (* SH'd *)
 
     thus "y = B" using IS.IH by auto
 
     thus "y = B" using IS.IH by auto
 
   qed
 
   qed
Línea 462: Línea 504:
 
   hence "balanceada_aux (w @ [B]) 1" using bal `x = A` by simp
 
   hence "balanceada_aux (w @ [B]) 1" using bal `x = A` by simp
  
   have hl2: "balanceada_aux (x#w) n ⟹ ∃m. balanceada_aux w m" for x w n
+
   have hl2: "balanceada_aux (x#w) n ⟹ ∃m. balanceada_aux w m"  
 +
    for x w n
 
   proof (cases x)
 
   proof (cases x)
 
     case A
 
     case A
Línea 474: Línea 517:
 
   qed
 
   qed
  
   have "⟦balanceada_aux w n; u @ v = w⟧ ⟹ ∃ m. balanceada_aux v m" for u v w n
+
   have "⟦balanceada_aux w n; u @ v = w⟧ ⟹ ∃ m. balanceada_aux v m"  
 +
    for u v w n
 
   proof (induction w arbitrary: u v n)
 
   proof (induction w arbitrary: u v n)
 
     case Nil
 
     case Nil
Línea 495: Línea 539:
 
     qed
 
     qed
 
   qed
 
   qed
   moreover have "balanceada_aux (w @ [B]) 1" using bal `x = A` `y = B` by simp
+
   moreover have "balanceada_aux (w @ [B]) 1" using bal `x = A` `y = B`  
   ultimately have "u @ v = (w @ [B]) ⟹ ∃m. balanceada_aux v m" for u v by auto
+
    by simp
 +
   ultimately have "u @ v = (w @ [B]) ⟹ ∃m. balanceada_aux v m"  
 +
    for u v by auto
 
   moreover {
 
   moreover {
 
     fix u v
 
     fix u v
     have 1: "⟦u' ≠ []; v ≠ []; u' @ v = (x # w @ [y])⟧ ⟹ ¬(balanceada v)" for u'
+
     have 1: "⟦u' ≠ []; v ≠ []; u' @ v = (x # w @ [y])⟧ ⟹  
 +
            ¬(balanceada v)" for u'
 
       using postfix_con by auto
 
       using postfix_con by auto
     have "⟦v ≠ []; (x#u) @ v = (x # w @ [y])⟧ ⟹ ¬(balanceada v)" using 1[of "x#u"] by simp
+
     have "⟦v ≠ []; (x#u) @ v = (x # w @ [y])⟧ ⟹ ¬(balanceada v)"  
     hence "⟦v ≠ []; u @ v = (w @ [B])⟧ ⟹ ¬(balanceada_aux v 0)" using `y = B` by simp
+
      using 1[of "x#u"] by simp
 +
     hence "⟦v ≠ []; u @ v = (w @ [B])⟧ ⟹ ¬(balanceada_aux v 0)"  
 +
      using `y = B` by simp
 
   }
 
   }
   ultimately have hl3: "⟦v ≠ []; u @ v = (w @ [B])⟧ ⟹ ∃m. balanceada_aux v (Suc m)" for u v
+
   ultimately have hl3: "⟦v ≠ []; u @ v = (w @ [B])⟧ ⟹  
 +
                        ∃m. balanceada_aux v (Suc m)" for u v
 
     by (metis zero_induct) (* SH'd *)
 
     by (metis zero_induct) (* SH'd *)
  
  
   have hl4: "⟦balanceada_aux (v @ [B]) (Suc n); ⋀s t. v = s @ t ⟹ ∃m. balanceada_aux (t @ [B]) (Suc m)⟧
+
   have hl4: "⟦balanceada_aux (v @ [B]) (Suc n); ⋀s t. v = s @ t ⟹  
      ⟹ balanceada_aux v n" for v n
+
              ∃m. balanceada_aux (t @ [B]) (Suc m)⟧
 +
            ⟹ balanceada_aux v n" for v n
 
   proof (induction v arbitrary: n)
 
   proof (induction v arbitrary: n)
 
     case Nil
 
     case Nil
Línea 518: Línea 569:
  
 
     have "x#v' = [x] @ v'" by simp
 
     have "x#v' = [x] @ v'" by simp
     then obtain m where mDef: "balanceada_aux (v' @ [B]) (Suc m)" using IS.prems by blast
+
     then obtain m where mDef: "balanceada_aux (v' @ [B]) (Suc m)"  
     moreover have v'Postf: "⋀s t. v' = s @ t ⟹ ∃m. balanceada_aux (t @ [B]) (Suc m)"
+
      using IS.prems by blast
 +
     moreover have v'Postf: "⋀s t. v' = s @ t ⟹  
 +
                                  ∃m. balanceada_aux (t @ [B]) (Suc m)"
 
       using IS.prems by auto
 
       using IS.prems by auto
 
     ultimately have "balanceada_aux v' m" using IS.IH by simp
 
     ultimately have "balanceada_aux v' m" using IS.IH by simp
Línea 526: Línea 579:
 
     proof (cases x)
 
     proof (cases x)
 
       case A
 
       case A
       hence "balanceada_aux ((A # v') @ [B]) (Suc n)" using IS.prems by simp
+
       hence "balanceada_aux ((A # v') @ [B]) (Suc n)" using IS.prems  
 +
        by simp
 
       hence "balanceada_aux (v' @ [B]) (Suc (Suc n))" by simp
 
       hence "balanceada_aux (v' @ [B]) (Suc (Suc n))" by simp
 
       hence "balanceada_aux v' (Suc n)" using IS.IH v'Postf by simp
 
       hence "balanceada_aux v' (Suc n)" using IS.IH v'Postf by simp
Línea 532: Línea 586:
 
     next
 
     next
 
       case B
 
       case B
       hence "balanceada_aux ((B # v') @ [B]) (Suc n)" using IS.prems by simp
+
       hence "balanceada_aux ((B # v') @ [B]) (Suc n)" using IS.prems  
 +
        by simp
 
       hence 1: "balanceada_aux ( v' @ [B]) n" using IS.prems by simp
 
       hence 1: "balanceada_aux ( v' @ [B]) n" using IS.prems by simp
  
 
       have "n = Suc m" using 1 mDef balanceada_aux_unico by simp
 
       have "n = Suc m" using 1 mDef balanceada_aux_unico by simp
       thus "balanceada_aux (x # v') n" using `balanceada_aux v' m` `x = B` by simp
+
       thus "balanceada_aux (x # v') n"  
 +
        using `balanceada_aux v' m` `x = B` by simp
 
     qed
 
     qed
 
   qed
 
   qed
 
   moreover note `balanceada_aux (w @ [B]) 1`
 
   moreover note `balanceada_aux (w @ [B]) 1`
   moreover have "w = s @ t ⟹ ∃m. balanceada_aux (t @ [B]) (Suc m)" for s t using hl3 by simp
+
   moreover have "w = s @ t ⟹ ∃m. balanceada_aux (t @ [B]) (Suc m)"  
 +
    for s t using hl3 by simp
 
   ultimately have "balanceada_aux w 0" by simp
 
   ultimately have "balanceada_aux w 0" by simp
 
   thus "x = A ∧ y = B ∧ balanceada w" using `x = A` `y = B`by simp
 
   thus "x = A ∧ y = B ∧ balanceada w" using `x = A` `y = B`by simp
Línea 549: Línea 606:
 
   shows "¬ balanceada v"
 
   shows "¬ balanceada v"
 
proof -
 
proof -
   have "⟦balanceada_aux (u @ v) n; balanceada v⟧ ⟹ balanceada_aux u n" for n
+
   have "⟦balanceada_aux (u @ v) n; balanceada v⟧ ⟹ balanceada_aux u n"  
 +
    for n
 
   proof (induction u arbitrary: n)
 
   proof (induction u arbitrary: n)
 
     case Nil
 
     case Nil
Línea 561: Línea 619:
 
       hence "balanceada_aux (A # u' @ v) n" using IS.prems by simp
 
       hence "balanceada_aux (A # u' @ v) n" using IS.prems by simp
 
       hence "balanceada_aux (u' @ v) (Suc n)" by simp
 
       hence "balanceada_aux (u' @ v) (Suc n)" by simp
       hence "balanceada_aux u' (Suc n)" using `balanceada v` IS.IH by simp
+
       hence "balanceada_aux u' (Suc n)" using `balanceada v` IS.IH  
 +
        by simp
 
       thus ?thesis using `x = A` by simp
 
       thus ?thesis using `x = A` by simp
 
     next
 
     next
Línea 600: Línea 659:
 
         show ?thesis
 
         show ?thesis
 
         proof cases
 
         proof cases
           assume "∃u v. w = u @ v ∧ u ≠ [] ∧ v ≠ [] ∧ balanceada u ∧ balanceada v"
+
           assume "∃u v. w = u @ v ∧ u ≠ [] ∧ v ≠ [] ∧  
           then obtain u v where "w = u @ v" and "u ≠ []" and "v ≠ []" and "balanceada u"
+
                        balanceada u ∧ balanceada v"
 +
           then obtain u v where "w = u @ v" and  
 +
                                "u ≠ []" and  
 +
                                "v ≠ []" and  
 +
                                "balanceada u"
 
             and "balanceada v" by blast
 
             and "balanceada v" by blast
  
           have "u ∈ S" using `w = u @ v` `v ≠ []` `balanceada u` IS by simp
+
           have "u ∈ S" using `w = u @ v` `v ≠ []` `balanceada u` IS  
           moreover have "v ∈ S" using `w = u @ v` `u ≠ []` `balanceada v` IS by simp
+
            by simp
 +
           moreover have "v ∈ S"  
 +
            using `w = u @ v` `u ≠ []` `balanceada v` IS by simp
 
           ultimately show "w ∈ S" using S3 `w = u @ v` by simp
 
           ultimately show "w ∈ S" using S3 `w = u @ v` by simp
 
         next
 
         next
           assume "∄u v. w = u @ v ∧ u ≠ [] ∧ v ≠ [] ∧ balanceada u ∧ balanceada v"
+
           assume "∄u v. w = u @ v ∧ u ≠ [] ∧ v ≠ [] ∧  
           hence 1: "⟦u @ v = w; u ≠ []; v ≠ []; balanceada u⟧ ⟹ ¬ balanceada v" for u v by auto
+
                        balanceada u ∧ balanceada v"
 +
           hence 1: "⟦u @ v = w; u ≠ []; v ≠ []; balanceada u⟧ ⟹  
 +
                    ¬ balanceada v" for u v by auto
  
           have "w = x # y # w''" using `w = x # w'` `w' = y # w''` by simp
+
           have "w = x # y # w''" using `w = x # w'` `w' = y # w''`  
 +
            by simp
 
           moreover have "∃ u z. y # w'' = u @ [z]"
 
           moreover have "∃ u z. y # w'' = u @ [z]"
 
           proof -
 
           proof -
Línea 630: Línea 698:
 
           then obtain u z where "w = x # u @ [z]" by blast
 
           then obtain u z where "w = x # u @ [z]" by blast
 
           hence "balanceada (x # u @ [z])" using `balanceada w` by simp
 
           hence "balanceada (x # u @ [z])" using `balanceada w` by simp
           moreover have "⟦s ≠ []; t ≠ []; s @ t = x # u @ [z]⟧ ⟹ ¬ balanceada t" for s t
+
           moreover have "⟦s ≠ []; t ≠ []; s @ t = x # u @ [z]⟧ ⟹  
 +
                        ¬ balanceada t" for s t
 
           proof (cases "balanceada s")
 
           proof (cases "balanceada s")
 
             case True
 
             case True
Línea 643: Línea 712:
 
             hence "x # u @ [z] = s @ t" ..
 
             hence "x # u @ [z] = s @ t" ..
 
             thus ?thesis
 
             thus ?thesis
               using balanceada_completo_aux2 `balanceada w` `¬ balanceada s` `w = x # u @ [z]` by simp
+
               using balanceada_completo_aux2  
 +
                    `balanceada w`  
 +
                    `¬ balanceada s`  
 +
                    `w = x # u @ [z]`  
 +
              by simp
 
           qed
 
           qed
 
           ultimately have "x = A" and "z = B" and "balanceada u"
 
           ultimately have "x = A" and "z = B" and "balanceada u"
 
             using balanceada_completo_aux1[of x u z] by auto
 
             using balanceada_completo_aux1[of x u z] by auto
           moreover have "u ∈ S" using `w = x # u @ [z]` IS `balanceada u` by simp
+
           moreover have "u ∈ S"  
           hence "x # u @ [z] ∈ S" using S2 `u ∈ S` `x = A` `z = B` by simp
+
            using `w = x # u @ [z]` IS `balanceada u` by simp
 +
           hence "x # u @ [z] ∈ S" using S2 `u ∈ S` `x = A` `z = B`  
 +
            by simp
 
           thus "w ∈ S" using `w = x # u @ [z]` by simp
 
           thus "w ∈ S" using `w = x # u @ [z]` by simp
 
         qed
 
         qed

Revisión del 16:52 28 feb 2019

chapter {* R8: Gramáticas libres de contexto *}

theory R8_Gramaticas_libre_de_contexto_alu
imports Main
begin

text {*
  En esta relación se definen dos gramáticas libres de contexto y se
  demuestra que son equivalentes. Además, se define por recursión una
  función para reconocer las palabras de la gramática y se demuestra que
  es correcta y completa. *}

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 1. Una gramática libre de contexto para las expresiones
  parentizadas es
     S ⟶ ε | '(' S ')' | SS
  definir inductivamente la gramática S usando A y B para '(' y ')',
  respectivamente. 
  ------------------------------------------------------------------ *}

datatype alfabeto = A | B

inductive_set S :: "alfabeto list set" where
  S1: "[] ∈ S" 
| S2: "w ∈ S ⟹ [A] @ w @ [B] ∈ S" 
| S3: "v ∈ S ⟹ w ∈ S ⟹ v @ w ∈ S"

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 2. Otra gramática libre de contexto para las expresiones
  parentizadas es
     T ⟶ ε | T '(' T ')'
  definir inductivamente la gramática T usando A y B para '(' y ')',
  respectivamente. 
  ------------------------------------------------------------------ *}

inductive_set T :: "alfabeto list set" where
  T1: "[] ∈ T" 
| T2: "v ∈ T ⟹ w ∈ T ⟹ v @ [A] @ w @ [B] ∈ T"

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 3. Demostrar que T está contenido en S. 
  ------------------------------------------------------------------ *}

(* benber alfmarcua antramhur *)
lemma T_en_S: 
  assumes "w ∈ T"  
  shows   "w ∈ S"
proof -
  have "w ∈ T ⟹ w ∈ S"
  proof (induction rule: T.induct)
    show "[] ∈ S" by (rule S1)
  next
    fix v w
    assume "w ∈ S"
    hence "[A] @ w @ [B] ∈ S" by (rule S2)
    moreover assume "v ∈ S"
    ultimately show "v @ [A] @ w @ [B] ∈ S" using S3 by simp
  qed
  thus ?thesis using assms .
qed

(* cammonagu *)
declare S1 [iff] S2[intro!,simp]

(* cammonagu *)
declare T1 [iff]

(* cammonagu *)
lemma T2ImpS: "w ∈ T ⟹ w ∈ S"
  apply (erule T.induct)
    apply simp
  apply (blast intro: S3)
done

(* cammonagu *)
lemma T_en_S1: 
  assumes "w ∈ T"  
  shows   "w ∈ S"
proof -
  have "w ∈ T ⟹ w ∈ S" using assms by (rule T2ImpS)
  thus ?thesis using assms .
qed

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 4. Demostrar que S está contenido en T. 
  ------------------------------------------------------------------ *}

(* benber *)
lemma S_en_T: 
  "w ∈ S ⟹ w ∈ T"
proof (induction rule: S.induct)
  show "[] ∈ T" by (rule T1)
next
  fix w

  have "[] ∈ T" by (rule T1)
  moreover assume "w ∈ T"
  ultimately have "[] @ [A] @ w @ [B] ∈ T" by (rule T2)
  thus "[A] @ w @ [B] ∈ T" by simp
next
  fix v w
  assume "v ∈ T"
  moreover assume "w ∈ T"
  moreover have "⟦v ∈ T; w ∈ T⟧ ⟹ v @ w ∈ T" for v w
  proof (induction "length w + length v" 
         arbitrary: w v 
         rule: less_induct)
    case IH: less

    show "v @ w ∈ T"
    proof (cases w rule: T.cases)
      show "w ∈ T" using `w ∈ T`.
    next
      assume "w = []"
      thus "v @ w ∈ T" using `v ∈ T` by simp
    next
      fix w1 w2
      assume "w1 ∈ T" and "w2 ∈ T"
      assume "w = w1 @ [A] @ w2 @ [B]"
      hence 1: "v @ w = v @ w1 @ [A] @ w2 @ [B]" by simp

      have "length w1 < length w" using `w = w1 @ [A] @ w2 @ [B]` 
        by simp
      hence "length v + length w1 < length v + length w" by simp
      moreover note `v ∈ T`
      moreover note `w1 ∈ T`
      ultimately have "v @ w1 ∈ T" using IH by simp
      moreover note `w2 ∈ T`
      ultimately have "(v @ w1) @ [A] @ w2 @ [B] ∈ T" by (rule T2)
      thus "v @ w ∈ T" using 1 by simp
    qed
  qed
  ultimately show "v @ w ∈ T" by simp
qed

(* alfmarcua antramhur *)
lemma S_en_T_2: 
  "w ∈ S ⟹ w ∈ T"
proof (induction rule: S.induct)
  show "[] ∈ T" by (rule T1)
next
  fix w
  assume "w ∈ T"
  have "[] @ [A] @ w @ [B] ∈ T" using T1 `w ∈ T` by (rule T2)
  then show "[A] @ w @ [B] ∈ T" by (simp only: List.append.append_Nil)
next
  fix w v
  assume "v ∈ T"
  show "w ∈ T ⟹ v @ w ∈ T"
  proof (induction rule: T.induct)
    show "v @ [] ∈ T" using `v ∈ T` 
      by (simp only: List.append.right_neutral)
  next
    fix va w
    have "v @ va ∈ T ⟹ w ∈ T ⟹ (v @ va) @ [A] @ w @ [B] ∈ T " 
      by (rule T2)
    then show "v @ va ∈ T ⟹ w ∈ T ⟹ v @ va @ [A] @ w @ [B] ∈ T " 
      by (simp only: List.append_assoc)
  qed
qed

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 4. Demostrar que S y T son iguales. 
  ------------------------------------------------------------------ *}

(* benber cammonagu antramhur *)
lemma S_igual_T:
  "S = T"
  using T_en_S S_en_T by auto

(* alfmarcua *)
lemma S_igual_T_2:
  "S = T"
proof (rule equalityI)
  show "S ⊆ T" using S_en_T by (rule subsetI)
next
  show "T ⊆ S" using T_en_S by (rule subsetI)
qed

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 5. En lugar de una gramática, se puede usar el siguiente
  procedimiento para determinar si la cadena es una sucesión de
  paréntesis bien balanceada: se recorre la cadena de izquierda a
  derecha contando cuántos paréntesis de necesitan para que esté bien
  balanceada. Si el contador al final de la cadena es 0, la cadena está
  bien balanceada.

  Definir la función
     balanceada :: alfabeto list ⇒ bool
  tal que (balanceada w) se verifica si w está bien balanceada. Por
  ejemplo, 
     balanceada [A,A,B,B] = True
     balanceada [A,B,A,B] = True
     balanceada [A,B,B,A] = False
  Indicación: Definir balanceada  usando la función auxiliar 
     balanceada_aux :: alfabeto list ⇒ nat ⇒ bool
  tal que (balanceada_aux w 0) se verifica si w está bien balanceada.
  ------------------------------------------------------------------ *}

(* benber alfmarcua antramhur *)
(* balanceada_aux w n = True si y solo si ([A]*n) @ w es balanceada *)
fun balanceada_aux :: "alfabeto list ⇒ nat ⇒ bool" where
  "balanceada_aux [] 0 = True"
| "balanceada_aux [] (Suc n) = False"
| "balanceada_aux (B#w) 0 = False"
| "balanceada_aux (B#w) (Suc n) = balanceada_aux w n"
| "balanceada_aux (A#w) n = balanceada_aux w (Suc n)"

fun balanceada :: "alfabeto list ⇒ bool" where
  "balanceada w = balanceada_aux w 0"

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 6. Demostrar que balanceada es un reconocedor correcto de la
  gramática S; es decir, 
     w ∈ S ⟹ balanceada w
  ------------------------------------------------------------------ *}

(* benber *)
lemma balanceada_correcto_aux1: 
  "balanceada_aux w n ⟹ balanceada_aux (w @ [B]) (Suc n)"
proof (induction w arbitrary: n)
  case Nil
  assume "balanceada_aux [] n"
  thus ?case by simp
next
  case IS: (Cons x w)
  show ?case
  proof (cases x)
    case A
    note `balanceada_aux (x#w) n`
    hence "balanceada_aux (A#w) n" using `x = A` by simp
    hence "balanceada_aux w (Suc n)" by simp
    hence "balanceada_aux (w@[B]) (Suc (Suc n))" using IS.IH by simp
    hence "balanceada_aux ((A#w)@[B]) (Suc n)" by simp
    thus ?thesis using `x = A` by simp
  next
    case B
    hence 1: "balanceada_aux (B#w) n" using IS.prems by simp

    show ?thesis
    proof (cases n)
      case 0
      hence "balanceada_aux (B#w) 0" using 1 by simp
      hence "False" by simp
      thus ?thesis ..
    next
      case (Suc m)
      hence "balanceada_aux (B#w) (Suc m)" using 1 by simp
      hence "balanceada_aux w m" by simp
      hence "balanceada_aux (w@[B]) (Suc m)" using IS.IH by simp
      hence "balanceada_aux (w@[B]) n" using `n = Suc m` by simp
      hence "balanceada_aux (B#(w@[B])) (Suc n)" by simp
      thus ?thesis using `x = B` by simp
    qed
  qed
qed

lemma balanceada_correcto_aux2:
  assumes "balanceada v"
  shows "balanceada_aux w n ⟹ balanceada_aux (w @ v) n"
proof (induction w arbitrary: n)
  case Nil
  hence "n = 0" using balanceada_aux.elims by auto
  thus ?case using assms by simp
next
  case IS: (Cons x w)
  show "balanceada_aux ((x#w)@v) n"
  proof (cases x)
    case A
    hence "balanceada_aux (A#w) n" using IS.prems by simp
    hence "balanceada_aux w (Suc n)" by simp
    hence "balanceada_aux (w@v) (Suc n)" using IS.IH by simp
    hence "balanceada_aux (A#(w@v)) n" by simp
    thus ?thesis using `x = A` by simp
  next
    case B
    hence 1: "balanceada_aux (B#w) n" using IS.prems by simp

    show ?thesis
    proof (cases n)
      case 0
      hence "balanceada_aux (B#w) 0" using 1 by simp
      hence "False" by simp
      thus ?thesis ..
    next
      case (Suc m)
      hence "balanceada_aux (B#w) (Suc m)" using 1 by simp
      hence "balanceada_aux w m" by simp
      hence "balanceada_aux (w@v) m" using IS.IH by simp
      hence "balanceada_aux (B#(w@v)) (Suc m)" by simp
      thus ?thesis using `x = B` `n = Suc m` by simp
    qed
  qed
qed

lemma balanceada_correcto:
  "w ∈ S ⟹ balanceada w"
proof (induction rule: S.induct)
  case S1
  have "balanceada [] = balanceada_aux [] 0" by simp
  also have "..." by simp
  finally show ?case.
next
  case S2
  fix w
  assume "balanceada w"
  hence "balanceada_aux w 0" by simp
  hence "balanceada_aux (w@[B]) 1" using balanceada_correcto_aux1 
    by simp
  hence "balanceada_aux ([A] @ w @ [B]) 0" by simp
  thus "balanceada ([A] @ w @ [B])" by simp
next
  case S3
  thus ?case using balanceada_correcto_aux2 by auto
qed

(* alfmarcua antramhur *)
lemma balanceada_correcto_aux3:
  shows "balanceada_aux v m ⟹ 
         balanceada_aux w n ⟹ 
         balanceada_aux (v @ w) (m+n)"
proof (induction v arbitrary: n m)
  case Nil
  then show ?case 
  proof (cases m)
    case 0
    then have "balanceada_aux w (m + n)" using Nil.prems(2) 
      by (simp only:Groups.monoid_add_class.add.left_neutral)
    then show ?thesis  by (simp only:List.append.append_Nil)
  next
    case (Suc mm)
    then have "False" using Nil.prems(1) 
      by (simp only: balanceada_aux.simps(2))
    then show ?thesis ..
  qed
next
  case IS:(Cons a v)
  show "balanceada_aux ((a # v) @ w) (m + n)"
  proof (cases a)
    define k :: nat where "k = m + 1"
    case A
    then have "balanceada_aux v k" using `k = m + 1` IS.prems(1) 
      by simp
    then have "balanceada_aux (v @ w) (k + n)" using IS.prems(2)  
      by (rule IS.IH)
    then have "balanceada_aux (v @ w) (Suc(m + n))" using `k = m + 1` 
      by simp
    then have "balanceada_aux (A # (v @ w)) (m + n)" 
      by (simp only: balanceada_aux.simps(5))
    then show ?thesis using `a = A` 
      by (simp only:List.append.append_Cons)
  next
    case B
    then show ?thesis
    proof (cases m)
      case 0
      then have "False" using IS.prems(1) `a = B` 
        by (simp only: balanceada_aux.simps(3))
      then show ?thesis ..
    next
      case (Suc mm)
      hence "balanceada_aux v mm" using IS.prems(1) `a = B` 
        by (simp only: balanceada_aux.simps(4))
      then have "balanceada_aux (v @ w) (mm + n)" using IS.prems(2) 
        by (rule IS.IH)
      then have "balanceada_aux (B # (v @ w)) (Suc (mm + n))" 
        by (simp only: balanceada_aux.simps(4))
      then have "balanceada_aux (B # (v @ w)) (m + n)" 
        using `m = Suc mm` by (simp only: Nat.plus_nat.add_Suc)
      then show ?thesis using `a=B`  
        by (simp only:List.append.append_Cons)
    qed
  qed
qed

lemma balanceada_correcto_2:
  "w ∈ S ⟹ balanceada w"
proof (induction rule: S.induct)
  case S1
  have "balanceada_aux [] 0" by (simp only: balanceada_aux.simps(1))
  then show ?case by (simp only: balanceada.simps)
next
  case (S2 w)
  then have 1:"balanceada_aux w 0" by (simp only: balanceada.simps)
  have "balanceada_aux [] 0" by (simp only: balanceada_aux.simps(1))
  then have 2:"balanceada_aux (B#[]) (Suc 0)" 
    by (simp only: balanceada_aux.simps(4))
  have "balanceada_aux w 0 ⟹ 
        balanceada_aux [B] (Suc 0) ⟹  
        balanceada_aux (w @ [B]) (0+Suc 0)" 
    by (rule balanceada_correcto_aux3)
  then have "balanceada_aux (w @ [B]) (Suc 0)" using 1 2 
    by (simp only:Groups.monoid_add_class.add.left_neutral)
  then have "balanceada_aux (A # (w @ [B])) 0" 
    by (simp only: balanceada_aux.simps(5))
  then have "balanceada_aux ([A] @ w @ [B]) 0" 
    by (simp only: List.append_Cons List.append_Nil)
  then show ?case by (simp only: balanceada.simps)
next
  case (S3 v w)
  then have 1:"balanceada_aux w 0" by (simp only: balanceada.simps)
  have 2:"balanceada_aux v 0" using S3(3) 
    by (simp only: balanceada.simps)
  have "balanceada_aux v 0 ⟹ 
        balanceada_aux w 0 ⟹  
        balanceada_aux (v @ w) (0+0)" 
    by (rule balanceada_correcto_aux3)
  then have "balanceada_aux (v @ w) 0" using 1 2 
    by (simp only:Groups.monoid_add_class.add.right_neutral)
  then show ?case by (simp only: balanceada.simps)
qed

text {*  
  --------------------------------------------------------------------- 
  Ejercicio 7. Demostrar que balanceada es un reconocedor completo de 
  la gramática S; es decir, 
     balanceada w ⟹ w ∈ S 
  ------------------------------------------------------------------ *}

(* benber *)
lemma balanceada_aux_unico: 
  "⟦balanceada_aux w k; balanceada_aux w l⟧ ⟹ k = l" for w k l
proof (induction w arbitrary: k l)
  case Nil
  hence "k = 0 ∧ l = 0" using balanceada_aux.elims by auto
  thus ?case by simp
next
  case IS: (Cons x w')
  show ?case
  proof (cases x)
    case A
    thus ?thesis using IS by auto
  next
    case B
    show ?thesis
    proof (cases k)
      case 0
      hence "False" using IS.prems `x = B` by simp
      thus ?thesis ..
    next
      case (Suc k')
      hence "balanceada_aux w' k'" using IS.prems `x = B` by simp

      show ?thesis
      proof (cases l)
        case 0
        hence "False" using IS.prems `x = B` by simp
        thus ?thesis ..
      next
        case (Suc l')
        hence "balanceada_aux w' l'" using IS.prems `x = B` by simp
        thus ?thesis 
          using `balanceada_aux w' k'` IS.IH `k = Suc k'` `l = Suc l'` 
          by auto
      qed
    qed
  qed
qed

lemma balanceada_completo_aux1:
  "⟦balanceada (x # w @ [y]); 
    ⋀u v. u ≠ [] ∧ v ≠ [] ∧ u @ v = x # w @ [y] ⟶ ¬ (balanceada v)⟧
    ⟹ x = A ∧ y = B ∧ balanceada w"
proof -
  assume "balanceada (x # w @ [y])"
  hence bal: "balanceada_aux ( x # w @ [y] ) 0" by simp

  assume postfix_con: "⋀u v. u ≠ [] ∧ v ≠ [] ∧ u @ v = x # w @ [y] ⟶ 
                             ¬ (balanceada v)"

  have "x = A"
  proof (rule ccontr)
    assume "x ≠ A"
    hence "x = B" using alfabeto.exhaust by blast
    thus "False" using bal by simp
  qed

  have hl1: "balanceada_aux (w @ [y]) n ⟹ y = B" for w y n
  proof (induction w arbitrary: n)
    case IB: Nil
    show "y = B"
    proof (rule ccontr)
      assume "y ≠ B"
      hence "y = A" using alfabeto.exhaust by blast
      thus "False" using IB by simp
    qed
  next
    case IS: (Cons x w)
    hence "balanceada_aux (x # w @ [y]) n" by simp
    hence "∃m. balanceada_aux (w @ [y]) m" using balanceada_aux.elims(2) 
      by blast (* SH'd *)
    thus "y = B" using IS.IH by auto
  qed

  have "y = B" using bal hl1[of "(x#w)"] by simp
  hence "balanceada_aux (w @ [B]) 1" using bal `x = A` by simp

  have hl2: "balanceada_aux (x#w) n ⟹ ∃m. balanceada_aux w m" 
    for x w n
  proof (cases x)
    case A
    moreover assume "balanceada_aux (x#w) n"
    ultimately show ?thesis by auto
  next
    case B
    moreover assume "balanceada_aux (x#w) n"
    ultimately have "balanceada_aux (B#w) n" by simp
    thus ?thesis by (cases n) auto
  qed

  have "⟦balanceada_aux w n; u @ v = w⟧ ⟹ ∃ m. balanceada_aux v m" 
    for u v w n
  proof (induction w arbitrary: u v n)
    case Nil
    hence "v = []" by simp
    hence "balanceada_aux v 0" by simp
    thus ?case ..
  next
    case IS: (Cons x w')
    then obtain m where mDef: "balanceada_aux w' m" using hl2 by blast

    show ?case
    proof (cases u)
      case Nil
      hence "balanceada_aux v n" using IS by simp
      thus ?thesis ..
    next
      case (Cons y u')
      hence "w' = u' @ v" using IS.prems by simp
      thus ?thesis using IS.IH mDef by simp
    qed
  qed
  moreover have "balanceada_aux (w @ [B]) 1" using bal `x = A` `y = B` 
    by simp
  ultimately have "u @ v = (w @ [B]) ⟹ ∃m. balanceada_aux v m" 
    for u v by auto
  moreover {
    fix u v
    have 1: "⟦u' ≠ []; v ≠ []; u' @ v = (x # w @ [y])⟧ ⟹ 
             ¬(balanceada v)" for u'
      using postfix_con by auto
    have "⟦v ≠ []; (x#u) @ v = (x # w @ [y])⟧ ⟹ ¬(balanceada v)" 
      using 1[of "x#u"] by simp
    hence "⟦v ≠ []; u @ v = (w @ [B])⟧ ⟹ ¬(balanceada_aux v 0)" 
      using `y = B` by simp
  }
  ultimately have hl3: "⟦v ≠ []; u @ v = (w @ [B])⟧ ⟹ 
                        ∃m. balanceada_aux v (Suc m)" for u v
    by (metis zero_induct) (* SH'd *)


  have hl4: "⟦balanceada_aux (v @ [B]) (Suc n); ⋀s t. v = s @ t ⟹ 
              ∃m. balanceada_aux (t @ [B]) (Suc m)⟧
             ⟹ balanceada_aux v n" for v n
  proof (induction v arbitrary: n)
    case Nil
    hence "balanceada_aux [B] (Suc n)" by simp
    thus "balanceada_aux [] n" by simp
  next
    case IS: (Cons x v')

    have "x#v' = [x] @ v'" by simp
    then obtain m where mDef: "balanceada_aux (v' @ [B]) (Suc m)" 
      using IS.prems by blast
    moreover have v'Postf: "⋀s t. v' = s @ t ⟹ 
                                  ∃m. balanceada_aux (t @ [B]) (Suc m)"
      using IS.prems by auto
    ultimately have "balanceada_aux v' m" using IS.IH by simp

    show ?case
    proof (cases x)
      case A
      hence "balanceada_aux ((A # v') @ [B]) (Suc n)" using IS.prems 
        by simp
      hence "balanceada_aux (v' @ [B]) (Suc (Suc n))" by simp
      hence "balanceada_aux v' (Suc n)" using IS.IH v'Postf by simp
      thus ?thesis using `x = A` by simp
    next
      case B
      hence "balanceada_aux ((B # v') @ [B]) (Suc n)" using IS.prems 
        by simp
      hence 1: "balanceada_aux ( v' @ [B]) n" using IS.prems by simp

      have "n = Suc m" using 1 mDef balanceada_aux_unico by simp
      thus "balanceada_aux (x # v') n" 
        using `balanceada_aux v' m` `x = B` by simp
    qed
  qed
  moreover note `balanceada_aux (w @ [B]) 1`
  moreover have "w = s @ t ⟹ ∃m. balanceada_aux (t @ [B]) (Suc m)" 
    for s t using hl3 by simp
  ultimately have "balanceada_aux w 0" by simp
  thus "x = A ∧ y = B ∧ balanceada w" using `x = A` `y = B`by simp
qed

lemma balanceada_completo_aux2: 
  assumes "balanceada (u @ v)" and "¬ balanceada u"
  shows "¬ balanceada v"
proof -
  have "⟦balanceada_aux (u @ v) n; balanceada v⟧ ⟹ balanceada_aux u n" 
    for n
  proof (induction u arbitrary: n)
    case Nil
    hence "n = 0" using balanceada_aux_unico by simp
    thus ?case by simp
  next
    case IS: (Cons x u')
    show ?case
    proof (cases x)
      case A
      hence "balanceada_aux (A # u' @ v) n" using IS.prems by simp
      hence "balanceada_aux (u' @ v) (Suc n)" by simp
      hence "balanceada_aux u' (Suc n)" using `balanceada v` IS.IH 
        by simp
      thus ?thesis using `x = A` by simp
    next
      case B
      hence 1: "balanceada_aux (B # u' @ v) n" using IS.prems by simp
      then obtain m where "Suc m = n" by (cases n) auto
      hence "balanceada_aux (B # u' @ v) (Suc m)" using 1 by simp
      hence "balanceada_aux u' m" using `balanceada v` IS.IH by simp
      hence "balanceada_aux (B # u') n" using `Suc m = n` by auto
      thus ?thesis using `x = B` by simp
    qed
  qed
  thus ?thesis using assms by auto
qed

lemma balanceada_completo:
  assumes "balanceada w"
  shows   "w ∈ S"
proof -
  have "balanceada w ⟹ w ∈ S"
  proof (induction "length w" arbitrary: w rule: less_induct)
    case IS: less
  
    show ?case
    proof (cases w)
      case Nil
      thus ?thesis using S1 by simp
    next
      case (Cons x w')
      show ?thesis
      proof (cases w')
        case Nil
        hence "¬ balanceada (x#w')" by (cases x) auto
        hence "False" using `w = x # w'`IS.prems by simp
        thus ?thesis ..
      next
        case (Cons y w'')
        show ?thesis
        proof cases
          assume "∃u v. w = u @ v ∧ u ≠ [] ∧ v ≠ [] ∧ 
                        balanceada u ∧ balanceada v"
          then obtain u v where "w = u @ v" and 
                                "u ≠ []" and 
                                "v ≠ []" and 
                                "balanceada u"
            and "balanceada v" by blast

          have "u ∈ S" using `w = u @ v` `v ≠ []` `balanceada u` IS 
            by simp
          moreover have "v ∈ S" 
            using `w = u @ v` `u ≠ []` `balanceada v` IS by simp
          ultimately show "w ∈ S" using S3 `w = u @ v` by simp
        next
          assume "∄u v. w = u @ v ∧ u ≠ [] ∧ v ≠ [] ∧ 
                        balanceada u ∧ balanceada v"
          hence 1: "⟦u @ v = w; u ≠ []; v ≠ []; balanceada u⟧ ⟹ 
                    ¬ balanceada v" for u v by auto

          have "w = x # y # w''" using `w = x # w'` `w' = y # w''` 
            by simp
          moreover have "∃ u z. y # w'' = u @ [z]"
          proof -
            have "∃ u y. (x :: alfabeto) # v = u @ [y]" for x v
            proof (induction v arbitrary: x)
              case Nil
              have "x # [] = [] @ [x]" by simp
              thus ?case by simp
            next
              case IS: (Cons z v')
              then obtain u' y' where "z # v' = u' @ [y']" by blast
              hence "x # z # v' = x # u' @ [y']" using IS by simp
              thus ?case by simp
            qed
            thus ?thesis by simp
          qed
          ultimately have "∃ u z. w = x # u @ [z]" by auto
          then obtain u z where "w = x # u @ [z]" by blast
          hence "balanceada (x # u @ [z])" using `balanceada w` by simp
          moreover have "⟦s ≠ []; t ≠ []; s @ t = x # u @ [z]⟧ ⟹ 
                         ¬ balanceada t" for s t
          proof (cases "balanceada s")
            case True
            moreover assume "s ≠ []"
            moreover assume "t ≠ []"
            moreover assume "s @ t = x # u @ [z]"
            ultimately show ?thesis using 1 `w = x # u @ [z]` by auto
          next
            case False

            assume "s @ t = x # u @ [z]"
            hence "x # u @ [z] = s @ t" ..
            thus ?thesis
              using balanceada_completo_aux2 
                    `balanceada w` 
                    `¬ balanceada s` 
                    `w = x # u @ [z]` 
              by simp
          qed
          ultimately have "x = A" and "z = B" and "balanceada u"
            using balanceada_completo_aux1[of x u z] by auto
          moreover have "u ∈ S" 
            using `w = x # u @ [z]` IS `balanceada u` by simp
          hence "x # u @ [z] ∈ S" using S2 `u ∈ S` `x = A` `z = B` 
            by simp
          thus "w ∈ S" using `w = x # u @ [z]` by simp
        qed
      qed
    qed
  qed
  thus ?thesis using assms .
qed

end