Theory KoenigLemma

(*  Formalization of König Lemma
   Fabian Fernando Serrano Suárez  UNAL Manizales
   Thaynara Arielly de Lima        Universidade Federal de Goiáis 
   Mauricio Ayala-Rincón           Universidade de Brasília
*)

(*<*)
theory KoenigLemma
 imports PropCompactness  
begin
(*>*)

section ‹König Lemma›

text‹This section formalizes König Lemma from the compactness theorem for propositional logic directly. ›


type_synonym 'a rel = "('a × 'a) set"

definition irreflexive_on ::  "'a set  'a rel  bool"
 where "irreflexive_on A r   (xA. (x, x)  r)"

definition transitive_on :: "'a set  'a rel  bool"
  where "transitive_on A r 
 (xA. yA. zA. (x, y)  r  (y, z)  r  (x, z)  r)"

definition total_on :: "'a set  'a rel  bool"
  where "total_on A r  (xA. yA. x  y  (x, y)  r  (y, x)  r)"

definition minimum ::  "'a set  'a 'a rel  bool"
  where "minimum A a r   (aA  (xA. x  a   (a,x)  r))"

definition predecessors :: "'a set 'a 'a rel   'a set"
  where "predecessors A a r  {xA.(x, a)  r}"

definition height ::  "'a set 'a  'a rel  nat"
  where "height A a r     card (predecessors A a r)"

definition level ::  "'a set  'a rel  nat 'a set"
  where "level A r n  {xA. height A x r = n}"

definition imm_successors ::  "'a set  'a  'a rel  'a set"
  where "imm_successors A a r  
 {xA. (a,x) r  height A x r = (height A a r)+1}" 

definition strict_part_order ::  "'a set  'a rel  bool"
  where  "strict_part_order A r  irreflexive_on A r  transitive_on A r"

lemma minimum_element:
  assumes  "strict_part_order A r" and "minimum A a r" and "r={}"
  shows "A={a}"
proof(rule ccontr)
  assume hip: "A  {a}" show False
  proof(cases)
    assume  hip1: "A={}"
    have "aA" using `minimum A a r` by(unfold minimum_def, auto) 
    thus False using hip1 by auto
  next
    assume  "A  {}"
    hence "x. xa  xA" using hip by auto
    then obtain x where  "xa  xA" by auto
    hence "(a,x)r"  using `minimum A a r` by(unfold minimum_def, auto)
    hence "r  {}" by auto
    thus False using `r={}` by auto
  qed
qed

lemma spo_uniqueness_min:
  assumes  "strict_part_order A r" and  "minimum A a r" and "minimum A b r" 
  shows "a=b"
proof(rule ccontr)
  assume hip: "a  b"
  have "aA"and "bA" using assms(2-3) by(unfold minimum_def, auto)
  show False
  proof(cases)
    assume "r = {}"
    hence  "A={a}  A={b}"  using assms(1-3) minimum_element[of A r] by auto
    thus False using hip by auto
  next
    assume "r{}"
    hence 1: "(a,b)r  (b,a)r" using hip assms(2-3)
      by(unfold minimum_def, auto)    
    have  irr: "irreflexive_on A r" and tran: "transitive_on A r"     
    using assms(1) by(unfold strict_part_order_def, auto)
    have  "(a,a)r" using  `aA`  `bA` 1 tran by(unfold transitive_on_def, blast)
    thus False using  `aA`  irr  by(unfold irreflexive_on_def, blast)
  qed
qed

lemma emptyness_pred_min_spo:
  assumes  "minimum A a r" and "strict_part_order A r"
  shows  "predecessors A a r = {}"
proof(rule ccontr)
  have  irr:  "irreflexive_on A r" and tran: "transitive_on A r" using assms(2)
  by(unfold strict_part_order_def, auto)
  assume 1: "predecessors A a r  {}" show False
  proof-
    have "xA. (x,a) r" using 1  by(unfold predecessors_def, auto)
    then obtain x where "xA" and "(x,a) r" by auto
    hence "xa" using irr by (unfold irreflexive_on_def, auto)
    hence "(a,x)r" using  `xA` `minimum A a r` by(unfold minimum_def, auto)
    have  "aA" using  `minimum A a r` by(unfold minimum_def, auto)
    hence "(a,a)r" using `(a,x)r`  `(x,a) r`  `xA`  tran 
      by(unfold transitive_on_def, blast)
    thus False using `(a,a)r` `aA` irr  irreflexive_on_def
      by (unfold irreflexive_on_def, auto)
  qed
qed

lemma  emptyness_pred_min_spo2:
  assumes  "strict_part_order A r" and  "minimum A a r" 
  shows "xA.(predecessors A x r = {})  (x=a)" 
proof
  fix x
  assume  "x  A" 
  show "(predecessors A x r = {})  (x = a)"
  proof-
    have 1: "a  A" using  `minimum A a r`  by(unfold minimum_def, auto)
    have 2: "(predecessors A x r = {}) (x=a)"
    proof(rule impI)
      assume h: "predecessors A x r = {}"  show "x=a"
      proof(rule ccontr)
      assume  "x  a" 
      hence  "(a,x) r" using  `x  A` `minimum A a r`
        by(unfold minimum_def, auto)     
      hence  "a  predecessors A x r"
        using 1 by(unfold  predecessors_def,auto)
      thus False using h by auto 
    qed
  qed
  have 3: "x=a  (predecessors A x r = {})"
  proof(rule impI)
    assume "x=a"
    thus "predecessors A x r = {}" 
      using assms emptyness_pred_min_spo[of A a]  by auto
  qed
  show ?thesis using 2 3 by auto
   qed
qed

lemma height_minimum:
  assumes  "strict_part_order A r" and  "minimum A a r"
  shows "height  A a r = 0"
proof-
  have  "aA" using  `minimum A a r` by(unfold minimum_def, auto)
  hence "predecessors A a r = {}"
    using assms emptyness_pred_min_spo2[of A r]  by auto
  thus "height  A a r = 0" by(unfold height_def, auto) 
qed

lemma zero_level:
  assumes  "strict_part_order A r" 
  and "minimum A a r"  and  "xA. finite (predecessors A x r)"  
  shows "(level A r 0) = {a}"
proof-
  have "xA.(card (predecessors A x r) = 0)  (x=a)"
  using  assms emptyness_pred_min_spo2[of A r a] card_eq_0_iff by auto
  hence 1:  "xA.(height A x r = 0)  (x=a)"
    by(unfold height_def, auto)
  have "aA" using  `minimum A a r` by(unfold minimum_def, auto)
  thus ?thesis using assms 1  level_def[of A r 0] by auto
qed

lemma min_predecessor:
  assumes  "minimum A a r"
  shows  "xA. xa  apredecessors A x r"
proof
  fix x
  assume "xA"
  show "x  a  a  predecessors A x r"
  proof(rule impI)
    assume  "x  a"
    show "a  predecessors A x r"
    proof-
      have "(a,x)r" using `xA` `x  a` `minimum A a r` 
        by(unfold minimum_def, auto)
      hence "aA"  using  `minimum A a r` by(unfold minimum_def, auto)
      thus "apredecessors A x r" using `(a,x)r` 
        by(unfold predecessors_def, auto)
    qed
  qed
qed

lemma spo_subset_preservation: 
  assumes "strict_part_order A r" and "BA" 
  shows "strict_part_order B r" 
proof-  
  have  "irreflexive_on A r" and "transitive_on A r" 
    using  `strict_part_order A r` 
    by(unfold strict_part_order_def, auto)
  have 1: "irreflexive_on B r"
  proof(unfold irreflexive_on_def)
    show "xB. (x, x)  r"
    proof
      fix x
      assume "xB" 
      hence "xA" using  `BA` by auto
      thus "(x,x)r" using  `irreflexive_on A r`
        by (unfold irreflexive_on_def, auto)
    qed
  qed
  have 2:  "transitive_on B r"
  proof(unfold transitive_on_def)
    show "xB. yB. zB. (x, y)  r  (y, z)  r  (x, z)  r"
    proof
      fix x assume "xB"
      show "yB. zB. (x, y)  r  (y, z)  r  (x, z)  r"
      proof
        fix y  assume "yB"
        show "zB. (x, y)  r  (y, z)  r  (x, z)  r"
        proof 
          fix z  assume "zB"
          show "(x, y)  r  (y, z)  r  (x, z)  r"
          proof(rule impI)
            assume hip: "(x, y)  r  (y, z)  r" 
            show "(x, z)  r"
          proof-
            have "xA" and  "yA" and  "zA" using `xB` `yB` `zB` `BA`
              by auto
            thus "(x, z)  r" using hip `transitive_on A  r` by(unfold transitive_on_def, blast)
            qed
          qed
        qed
      qed
    qed
  qed
  thus "strict_part_order B r"
    using 1 2  by(unfold strict_part_order_def, auto)   
qed

lemma total_ord_subset_preservation:
  assumes "total_on A r" and  "BA"
  shows "total_on B r"
proof(unfold total_on_def)
  show  "xB. yB. x  y  (x, y)  r  (y, x)  r"
  proof
    fix x
    assume "xB" show " yB. x  y  (x, y)  r  (y, x)  r"
    proof 
      fix y
      assume "yB" 
      show  "x  y  (x, y)  r  (y, x)  r"  
      proof(rule impI)
        assume  "x  y"
        show "(x, y)  r  (y, x)  r"
        proof-
          have "xA  yA" using  `xB`  `yB` `BA` by auto
          thus  "(x, y)  r  (y, x)  r" 
            using  `x  y` `total_on A r` by(unfold total_on_def, auto) 
        qed
      qed
    qed
  qed
qed

definition maximum ::  "'a set  'a 'a rel  bool"
  where "maximum A a r   (aA  (xA. x  a  (x,a)  r))"

lemma maximum_strict_part_order:
  assumes "strict_part_order A r" and "A{}" and "total_on A r" 
  and "finite A"
  shows "(a. maximum A a r)" 
proof-
  have "strict_part_order A r  A{}  total_on A r  finite A
   (a. maximum A a r)"  using assms(4)
  proof(induct A rule:finite_induct)
    case empty
    then show ?case by auto
  next
    case (insert x A)  
    show "(a. maximum (insert x A) a r)"
  proof(cases "A={}")
    case True
    hence "insert x A ={x}" by simp
    hence  "maximum (insert x A) x r" by(unfold maximum_def, auto)
    then show ?thesis by auto
  next
    case False
    assume "A  {}"
    show "a. maximum (insert x A) a r"
    proof-
      have 1: "strict_part_order A r" 
        using insert(4) spo_subset_preservation by auto
      have 2: "total_on A r" using insert(6) total_ord_subset_preservation by auto
      have "a. maximum A a r" using 1  `A{}`  insert(1) 2 insert(3) by auto
      then obtain a where a: "maximum A a r" by auto
      hence  "aA" and "yA. y  a   (y,a)  r" by(unfold maximum_def, auto)
      have 3: "a(insert x A)" using `aA`  by auto
      have 4: "ax" using `aA` and  `x  A` by auto
      have  "x(insert x A)" by auto
      hence "(a,x)r  (x,a)r" using 3 4 `total_on (insert x A) r`
        by(unfold total_on_def, auto)
      thus "a. maximum (insert x A) a r"
      proof(rule disjE)
        have  "transitive_on (insert x A) r" using  insert(4) 
          by(unfold strict_part_order_def, auto) 
        assume casoa: "(a, x)  r"  
        have  "z(insert x A). z  x   (z,x)  r"
        proof
          fix z
          assume hip1: "z  (insert x A)"
          show "z  x  (z, x)  r"
          proof(rule impI)
            assume "z  x"
            hence hip2:  "zA" using `z  (insert x A)` by auto 
            thus "(z, x)  r" 
            proof(cases)
              assume "z=a" 
              thus "(z, x)  r" using `(a, x)  r` by auto 
            next
              assume "za"
              hence "(z,a)  r" using  `zA` `yA. y  a   (y,a)  r` by auto
              have "a(insert x A)" and "z(insert x A)" and  "x(insert x A)"
                using  `aA` `zA` by auto            
              thus  "(z, x)  r"
                using  `(z,a)  r` `(a, x)  r`  `transitive_on (insert x A) r`
                by(unfold transitive_on_def, blast) 
            qed
          qed
        qed
        thus "a. maximum (insert x A) a r"
          using  `x(insert x A)` by(unfold maximum_def, auto)
      next
        assume casob: "(x, a)  r"
        have  "z(insert x A). z  a   (z,a)  r"
        proof
          fix z
          assume hip1: "z  (insert x A)"
          show "z  a  (z, a)  r"
          proof(rule impI)
            assume "z  a" show  "(z, a)  r"
            proof- 
              have "zA  z=x" using `z  (insert x A)` by auto
              thus  "(z, a)  r"
              proof(rule disjE)
                assume  "z  A"
                thus  "(z, a)  r" 
                  using  `z  a` `yA. y  a   (y,a)  r` by auto
              next
                assume "z = x" 
                thus  "(z, a)  r" using `(x, a)  r` by auto
              qed
            qed
          qed
        qed
        thus "a. maximum (insert x A) a r" 
          using `a(insert x A)`  by(unfold maximum_def, auto)      
      qed
    qed
  qed
qed
  thus ?thesis using assms by auto
qed

lemma finiteness_union_finite_sets:
  fixes S :: "'a    'a set" 
  assumes "x. finite (S x)" and "finite A"
  shows "finite (aA. (S a))" using assms by auto

lemma uniqueness_level_aux:
  assumes "k>0"
  shows "(level A r n)  (level A r (n+k)) = {}" 
proof(rule ccontr)
  assume  "level A r n  level A r (n + k)  {}" 
  hence  "x. x(level A r n)  level A r (n + k)" by auto
  then obtain x where "x(level A r n)  level A r (n + k)" by auto
  hence "xA  height A x r = n" and "xA  height A x r = n+k"
    by(unfold level_def, auto)
  thus False using `k>0` by auto
qed

lemma uniqueness_level:
  assumes "nm" 
  shows "(level A r n)  (level A r m) = {}"
proof-
  have "n < m  m < n" using assms by auto
  thus ?thesis
  proof(rule disjE)
    assume "n < m"
    hence "k. k>0  m=n+k" by arith
    thus ?thesis using uniqueness_level_aux[of _ A r] by auto
  next
    assume "m < n"
    hence "k. k>0  n=m+k" by arith
    thus ?thesis using  uniqueness_level_aux[of _ A r] by auto
  qed
qed
 
definition tree ::  "'a set  'a rel  bool"
  where "tree A r  
 r  A × A  r{}  (strict_part_order A r)    (a. minimum A a r) 
 (aA. finite (predecessors A a r)  (total_on (predecessors A  a r) r))"

definition finite_tree::  "'a set  'a rel  bool"
  where
"finite_tree A r   tree A r  finite A"

abbreviation  infinite_tree::  "'a set  'a rel  bool" 
  where
"infinite_tree A r    tree A r  ¬ finite A"

definition enumerable_tree :: "'a set  'a rel  bool"  where
 "enumerable_tree A r  g. enumeration (g:: nat 'a)"

definition finitely_branching ::  "'a set  'a rel  bool"
  where  "finitely_branching  A r  (xA. finite (imm_successors A x r))"

definition sub_linear_order :: "'a set  'a set  'a rel  bool"
  where "sub_linear_order B A r    BA  (strict_part_order A r)  (total_on B r)"

definition path ::  "'a set  'a set  'a rel  bool"
  where "path  B A r  
 (sub_linear_order B A r) 
 (C. B  C  sub_linear_order C A r  B = C)"

definition finite_path:: "'a set  'a set  'a rel  bool"
  where "finite_path B A r   path  B A r  finite B"

definition infinite_path:: "'a set  'a set  'a rel  bool"
  where "infinite_path B A r   path  B A r   ¬ finite B"

lemma tree: 
  assumes "tree A r"
  shows
  "r  A × A" and "r{}" 
  and  "strict_part_order A r"
  and  "a. minimum A a r" 
  and  "(aA. finite (predecessors A a r)  (total_on (predecessors A  a r) r))"
  using `tree A r` by(unfold tree_def, auto)

lemma non_empty: 
  assumes "tree A r" shows "A{}"
proof-
  have "a. minimum A a r" using  `tree A r` tree[of A r] by auto
  hence "a. aA"  by(unfold minimum_def, auto)
  thus  "A{}" by auto
qed

lemma predecessors_spo:
  assumes "tree A r" 
  shows  "xA. strict_part_order (predecessors A x r) r"
proof- 
  have "irreflexive_on A r" and "transitive_on A r"  using `tree A r`
    by(unfold tree_def,unfold strict_part_order_def,auto) 
  thus ?thesis
proof(unfold strict_part_order_def)
  show "xA. irreflexive_on (predecessors A x r) r 
        transitive_on (predecessors A x r) r"
  proof
    fix x
    assume "xA"
    show "irreflexive_on (predecessors A x r) r  transitive_on (predecessors A x r) r"
    proof-
      have 1: "irreflexive_on (predecessors A x r) r"
      proof(unfold irreflexive_on_def)
        show "y(predecessors A x r). (y, y)  r"
        proof
          fix y
          assume "y(predecessors A x r)"
          hence "yA" by(unfold predecessors_def,auto)
          thus "(y, y)  r" using `irreflexive_on A r` by(unfold irreflexive_on_def,auto)
        qed
      qed
      have 2: "transitive_on (predecessors A x r) r"
      proof(unfold transitive_on_def)
        let ?B= "(predecessors A x r)"
        show "w?B. y?B. z?B. (w, y)  r  (y, z)  r  (w, z)  r"
        proof
          fix w assume "w?B"
         show "y?B. z?B. (w, y)  r  (y, z)  r  (w, z)  r"
         proof
           fix y assume "y?B"
           show "z?B. (w, y)  r  (y, z)  r  (w, z)  r"
           proof 
             fix z  assume "z?B"
             show "(w, y)  r  (y, z)  r  (w, z)  r"
             proof(rule impI)
               assume hip: "(w, y)  r  (y, z)  r" 
               show "(w, z)  r"
               proof-
                 have  "wA" and  "yA" and  "zA" using `w?B` `y?B` `z?B`
                   by(unfold predecessors_def,auto)
                 thus "(w, z)  r"
                   using hip `transitive_on A  r` by(unfold transitive_on_def, blast)
                 qed
               qed
             qed
           qed
         qed
       qed
       show
        "irreflexive_on (predecessors A x r) r  transitive_on (predecessors A x r) r"
       using 1 2 by auto
       qed
     qed
  qed
qed
       
lemma predecessors_maximum:
  assumes "tree A r" and  "minimum A a r"
  shows "xA. xa  (b. maximum (predecessors A x r) b r)"
proof
  fix x
  assume "xA"
  show "xa  (b. maximum (predecessors A x r) b r)"
  proof(rule impI)
    assume "xa"
    show "(b. maximum (predecessors A x r) b r)" 
    proof-
      have 1: "strict_part_order (predecessors A x r) r" 
        using  `tree A r` `xA`  predecessors_spo by auto
      have 2: "total_on (predecessors A x r) r" and 
           3: "finite (predecessors A x r)" and  "r  A × A"
        using  `tree A r` `xA` by(unfold tree_def, auto)
      have 4:  "(predecessors A x r){}" 
        using  `r  A × A`  `minimum A a r`  `xA`  `xa` 
              min_predecessor[of A a] by auto
      have 5: "A{}" using `tree A r` non_empty by auto
      show "(b. maximum (predecessors A x r) b r)" 
        using 1 2 3 4 5  maximum_strict_part_order by auto
    qed
  qed
qed

lemma non_empty_preds_in_tree: 
  assumes  "tree A r"  and  "card (predecessors A x r) = n+1"
  shows  "xA"
proof- 
  have  "r  A × A"  using `tree A r` by(unfold tree_def, auto)
  have "(predecessors A x r)  {}" using assms(2) by auto
  hence "yA. (y,x)r" by (unfold predecessors_def,auto)
  thus  "xA" using  `r  A × A` by auto
qed

lemma imm_predecessor:
  assumes  "tree A r"   
  and  "card (predecessors A x r) = n+1" and
  "maximum (predecessors A x r) b r"
  shows "height A b r = n"
proof- 
  have "transitive_on A r" and  "r  A × A" and  "irreflexive_on A r"
    using `tree A r`
    by (unfold tree_def, unfold strict_part_order_def, auto)
  have  "xA" using  assms(1) assms(2)  non_empty_preds_in_tree by auto
  have "strict_part_order (predecessors A x r) r"
    using `xA` `tree A r` predecessors_spo[of A r] by auto
  hence  "irreflexive_on (predecessors A x r) r" and
         "transitive_on (predecessors A x r) r"
    by(unfold strict_part_order_def, auto) 
  have "b(predecessors A x r)" 
    using `maximum (predecessors A x r) b r` by(unfold maximum_def, auto)
  have "total_on (predecessors A x r) r"
    using `xA` `tree A r` by(unfold tree_def, auto)
  have "card (predecessors A x r)>0 " using assms(2) by auto
  hence 1: "finite (predecessors A x r)"  using card_gt_0_iff by blast
  have  2: "b(predecessors A x r)" 
    using assms(3) by (unfold maximum_def,auto)
  hence "card ((predecessors A x r)-{b}) = n" 
    using 1  `card (predecessors A x r) = n+1`
    card_Diff_singleton[of b "(predecessors A x r)" ] by auto
  have "(predecessors A b r) = ((predecessors A x r)-{b})"
  proof(rule equalityI)
    show "(predecessors A b r)  (predecessors A x r - {b})" 
    proof
      fix y
      assume  "y (predecessors A b r)"
      hence "yA" and  "(y,b) r" by (unfold predecessors_def,auto)
      hence "yb" using `irreflexive_on A r` by(unfold irreflexive_on_def,auto)
      have "(b,x)r" using 2 by (unfold predecessors_def,auto)
      hence "bA"  using `r  A × A` by auto
      have "(y,x) r" using `xA` `yA` `bA`  `(y,b) r`  `(b,x)r` `transitive_on A r`
        by(unfold transitive_on_def, blast)    
      show "y(predecessors A x r - {b})" 
        using `yA` `(y,x) r` `yb` by(unfold predecessors_def, auto)
    qed
  next
    show "(predecessors A x r - {b})  (predecessors A b r)"
    proof
      fix y
      assume hip: "y(predecessors A x r - {b})" 
      hence "yb" and  "yA" by(unfold predecessors_def, auto)
      have "(y,b) r" using hip `maximum (predecessors A x r) b r`
        by(unfold maximum_def,auto)
      thus "y (predecessors A b r)" using `yA`
        by(unfold predecessors_def, auto)
    qed
  qed
  hence 3:  "card (predecessors A b r) = card (predecessors A x r - {b})" 
    by auto
  have "finite (predecessors A x r)" using `xA` `tree A r` by(unfold tree_def,auto)
  hence "card (predecessors A x r - {b}) = card (predecessors A x r)-1 " 
    using 2  card_Suc_Diff1 by auto
  hence "card (predecessors A b r) = n"
    using 3  `card (predecessors A x r) = n+1` by auto
  thus "height A b r = n" by (unfold height_def, auto)
qed
 
lemma height:
  assumes  "tree A r" and "height A x r = n+1"  
  shows "y. (y,x)r  height A y r = n"
proof -
  have 1: "card (predecessors A x r) = n+1" 
    using assms(2) by (unfold height_def, auto)
  have "a. minimum A a r" using `tree A r` by(unfold tree_def, auto) 
  then obtain a where a: "minimum A a r"  by auto
  have  "strict_part_order A r" using  `tree A r` tree[of A r]  by auto
  hence  "height  A a r = 0" using a  height_minimum[of A r] by auto
  hence "x  a" using assms(2) by auto
  have "xA"  using `tree A r`  1  non_empty_preds_in_tree by auto 
  hence "(b. maximum (predecessors A x r) b r)" 
    using `x  a` `tree A r` a predecessors_maximum[of A r a] by auto
  then obtain b where b: "(maximum (predecessors A x r) b r)" by auto
  hence "(b,x)r" by(unfold maximum_def, unfold predecessors_def,auto)
  thus "y. (y,x)r  height A y r = n"
    using  `tree A r` 1 b imm_predecessor[of A r] by auto 
qed

lemma level:
  assumes  "tree A r" and "x  (level A r (n+1))"  
  shows "y. (y,x)r  y  (level A r n)"
proof-
  have "height A x r = n+1"
    using `x (level A r (n+1))` by (unfold level_def, auto)
  hence "y. (y,x)r  height A y r = n" 
    using `tree A r` height[of A r] by auto 
  then obtain y where y:  "(y,x)r  height A y r = n" by auto
  have  "r  A × A"  using `tree A r` by(unfold tree_def,auto) 
  hence "yA" using y by auto
  hence "(y,x)r  y  (level A r n)" using y by(unfold level_def, auto)
  thus ?thesis by auto
qed
(*Para demostrar que en un árbol de ramificación los leveles son finites, se define
la siguiente función. *)
primrec set_nodes_at_level ::  "'a set  'a rel  nat 'a set" where
"set_nodes_at_level A r 0 = {a. (minimum A a r)}"
| "set_nodes_at_level A r (Suc n)  = (a (set_nodes_at_level A r n). imm_successors A a r)"

lemma set_nodes_at_level_zero_spo:
  assumes  "strict_part_order A r" and  "minimum A a r"
  shows "(set_nodes_at_level A r 0) = {a}"
proof-
  have "a(set_nodes_at_level A r 0)" using `minimum A a r` by auto
  hence 1: "{a}  (set_nodes_at_level A r 0)" by auto
  have 2:  "(set_nodes_at_level A r 0)  {a}"
  proof
    {fix x
    assume "x(set_nodes_at_level A r 0)"
    hence "minimum A x r" by auto
    hence "x=a" using assms  spo_uniqueness_min[of A r] by auto
    thus "x{a}" by auto}
  qed
  thus "(set_nodes_at_level A r 0) = {a}" using 1 2 by auto
qed

lemma height_level:
  assumes "strict_part_order A r"  and  "minimum A a r"
  and "x  set_nodes_at_level A r n"
  shows "height A x r = n"
proof-
  have
 "strict_part_order A r; minimum A a r; x  set_nodes_at_level A r n  
  height A x r = n" 
  proof(induct n arbitrary: x)
    case 0
    then show "height A x r = 0"
    proof-
      have "minimum A x r"  using `x  set_nodes_at_level A r 0` by auto
      thus "height A x r = 0"
        using `strict_part_order A r`  height_minimum[of A r]
        by auto
    qed
  next
    case (Suc n)
    then show ?case 
    proof-
      have  "x (a  (set_nodes_at_level A r n). (imm_successors A a r))"
        using Suc(4) by auto
      then  obtain a
        where hip1:  "a  (set_nodes_at_level A r n)" and hip2: "x (imm_successors A a r)" 
        by auto
      hence 1: "height A a r = n" using  Suc(1-3) by auto
      have "height A x r = (height A a r)+1" 
        using hip2 by(unfold imm_successors_def, auto)
      thus "height A x r = Suc n" using 1 by auto
    qed
  qed
  thus ?thesis using assms by auto
qed

lemma level_func_vs_level_def: 
  assumes  "tree A r"
  shows "set_nodes_at_level A r n = level A r n"   
proof(induct n)
  have 1: "strict_part_order A r" and
       2: "xA. finite (predecessors A x r)"
    using  `tree A r` tree[of A r] by auto 
  have "a. minimum A a r" using `tree A r` by(unfold tree_def, auto)
  then obtain a where a: "minimum A a r"  by auto
  case 0
  then show  "set_nodes_at_level A r 0 = level A r 0" 
  proof- 
    have "set_nodes_at_level A r 0 = {a}" using 1 a  set_nodes_at_level_zero_spo[of A r] by auto
    moreover 
    have "level A r 0 = {a}" using 1 2  a  zero_level[of A r] by auto
    ultimately
    show "set_nodes_at_level A r 0 = level A r 0" by auto
  qed
  next
    case (Suc n)
    assume  "set_nodes_at_level A r n = level A r n"
    show "set_nodes_at_level A r (Suc n) = level A r (Suc n)"
    proof(rule equalityI)
      show "set_nodes_at_level A r (Suc n)  level A r (Suc n)"
      proof(rule subsetI)
        fix x
        assume hip:  "x  set_nodes_at_level A r (Suc n)" show "x  level A r (Suc n)"
        proof- 
          have
          "set_nodes_at_level A r (Suc n) = (a  (set_nodes_at_level A r n). (imm_successors A a r))"
            by simp
          hence "x (a  (set_nodes_at_level A r n). (imm_successors A a r))"
            using hip by auto 
          then obtain a where hip1: "a  (set_nodes_at_level A r n)" and
            hip2:"x (imm_successors A a r)" by auto
          have "(a,x)r   height A x r = (height A a r)+1" 
            using hip2 by(unfold imm_successors_def, auto)
          moreover
          have "b. minimum A b r" using `tree A r` by(unfold tree_def, auto)
         then obtain b where b: "minimum A b r"  by auto
         have 1:  "r  A × A" and  "strict_part_order A r"
           using `tree A r` by(unfold tree_def, auto)     
         hence "height A a r = n" using b hip1  height_level[of A r] by auto
         ultimately
         have "(a,x)r  height A x r = n+1" by auto
         hence "xA  height A x r = n+1" using `r  A × A` by auto
         thus "x  level A r (Suc n)" by(unfold level_def, auto)
       qed
     qed
  next
    show "level A r (Suc n)  set_nodes_at_level A r (Suc n)"
    proof(rule subsetI)
      fix x
      assume hip: "x  level A r (Suc n)" show "x  set_nodes_at_level A r (Suc n)"
      proof-
        have  1: "xA  height A x r = n+1" using hip by(unfold level_def,auto)
        hence  "y. (y,x)r  height A y r = n" 
        using assms height[of A r] by auto
        then obtain y where y1: "(y,x)r"  and y2: "height A y r = n" by auto
        hence "x  (imm_successors A y r)" 
          using 1 by(unfold imm_successors_def, auto)
        moreover
        have  "r  A × A"  using `tree A r` by(unfold tree_def, auto)
        have "yA" using y1  `r  A × A` by auto
        hence "y level A r n" using y2 by(unfold level_def, auto)
        hence "y set_nodes_at_level A r n" using Suc by auto 
        ultimately
        show "x  set_nodes_at_level A r (Suc n)" by auto
      qed
    qed
  qed
qed

lemma pertenece_level:
  assumes "x  set_nodes_at_level A r n" 
  shows "xA" 
proof-
  have "x  set_nodes_at_level A r n  xA"
  proof(induct n) 
    case 0
    show  "x  A"  using  `x  set_nodes_at_level A r 0` minimum_def[of A x r] by auto
  next
    case (Suc n)
    then show "x  A"
    proof- 
      have "a  (set_nodes_at_level A r n). x imm_successors A a r"  
        using `x  set_nodes_at_level A r (Suc n)` by auto  
      then obtain a  where  a1:  "a  (set_nodes_at_level A r n)" and
        a2: "x imm_successors A a r" by auto
      show "x  A" using a2 imm_successors_def[of A a r] by auto   
    qed
  qed
  thus "x  A" using assms by auto
qed

lemma finiteness_set_nodes_at_levela:
  assumes  "xA. finite (imm_successors A x r)" and "finite (set_nodes_at_level A r n)"
  shows "finite (a (set_nodes_at_level A r n). imm_successors A a r)"
proof  
  show "finite (set_nodes_at_level A r n)" using assms(2) by simp
next
  fix x
  assume hip:  "x  set_nodes_at_level A r n" show  "finite (imm_successors A x r)"
  proof-  
    have "xA" using hip  pertenece_level[of x A r]  by auto 
    thus  "finite (imm_successors A x r)"  using assms(1) by auto 
  qed
qed

lemma finiteness_set_nodes_at_level:
  assumes "finite (set_nodes_at_level A r 0)" and  "finitely_branching A r"
  shows  "finite (set_nodes_at_level A r n)"
proof(induct n)
  case 0
  show "finite (set_nodes_at_level A r 0)" using assms  by auto
next
  case (Suc n)
  then show ?case
  proof -   
    have 1: "xA. finite (imm_successors A x r)"
      using assms by (unfold finitely_branching_def, auto)
    hence  "finite (a (set_nodes_at_level A r n). imm_successors A a r)"
      using Suc(1) finiteness_set_nodes_at_levela[of A r] by auto 
    thus "finite (set_nodes_at_level A r (Suc n))" by auto
  qed
qed

lemma finite_level:
  assumes  "tree A r" and "finitely_branching  A r" 
  shows  "finite (level A r n)" 
proof-
  have 1: "strict_part_order A r"  using `tree A r` tree[of A r] by auto
  have  "a. minimum A a r"  using `tree A r` tree[of A r] by auto
  then obtain a where "minimum A a r" by auto
  hence "finite (set_nodes_at_level A r 0)" 
    using 1  set_nodes_at_level_zero_spo[of A r] by auto
  hence "finite (set_nodes_at_level A r n)"
    using `finitely_branching  A r` finiteness_set_nodes_at_level[of A r] by auto
  thus  ?thesis using `tree A r` level_func_vs_level_def[of A r n] by auto
qed

lemma  finite_level_a:
  assumes "tree A r" and "n. finite (level A r n)"
  shows "finitely_branching A r"
proof(unfold finitely_branching_def)
  show  "xA. finite (imm_successors A x r)"
  proof
  fix x
  assume "xA"
  show "finite (imm_successors A x r)" using finitely_branching_def
  proof-
    let ?n = "(height A x r)"
    have "(imm_successors A x r)  (level A r (?n+1))"
      using imm_successors_def[of A x r] level_def[of A r "?n+1"] by auto 
    thus "finite (imm_successors A x r)"  using assms(2) by(simp add: finite_subset)   
  qed
qed
qed

lemma empty_predec: 
  assumes "xA. (x,y)r"  
  shows "predecessors A y r ={}" 
    using assms by(unfold predecessors_def, auto)

lemma level_element:
 "xA.n. x level A r n"
proof
  fix x
  assume hip: "xA" show "n. x  level A r n"
  proof-
    let ?n = "height A x r"
    have "xlevel A r ?n" using `xA`  by (unfold level_def, auto)
    thus "n. x  level A r n" by auto 
  qed
qed

lemma union_levels:
  shows "A =(n. level A r n)"
proof(rule equalityI)
  show "A  (n. level A r n)"
  proof(rule subsetI)
    fix x
    assume hip: "xA" show "x(n. level A r n)"
    proof-
      have "n. x level A r n"  
        using hip level_element[of A] by auto
      then obtain n where  "x level A r n" by auto
    thus ?thesis by auto 
  qed
qed
next
  show  "(n. level A r n)  A"
  proof(rule subsetI)
    fix x
    assume hip:  "x  (n. level A r n)" show "x  A"
    proof-
      obtain n where  "x level A r n" using hip by auto 
      thus "x  A" by(unfold level_def, auto)
    qed
  qed
qed

lemma path_to_node:
  assumes  "tree A r"  and  "x  (level A r (n+1))" 
  shows "k.(0k  kn) (y. (y,x)r  y  (level A r k))"
proof- 
  have "tree A r  x  (level A r (n+1))   
  k.(0k  kn) (y. (y,x)r  y  (level A r k))"
  proof(induction n arbitrary: x)
    have "r  A × A" and 1:  "strict_part_order A r" 
    and "a. minimum A a r"
    and 2: "xA. finite (predecessors A x r)"  
      using `tree A r` tree[of A r] by auto
    case 0
    show  "k. 0  k  k  0  (y. (y, x)  r  y  level A r k)"
    proof
      fix k
      show "0  k  k  0  (y. (y, x)  r  y  level A r k)"
      proof(rule impI)
        assume hip:  "0  k  k  0"
        show "(y. (y, x)  r  y  level A r k)" 
        proof-
          have "k=0" using hip  by auto
          thus "(y. (y, x)  r  y  level A r k)"
            using `tree A r`  `x  (level A r (0 + 1))` level[of A r ]  by auto
        qed      
      qed
    qed
    next
      case (Suc n)
      show "k. 0  k  k  Suc n  (y. (y, x)  r  y  level A r k)"
  proof(rule allI, rule impI)
    fix k 
    assume hip:  "0  k  k  Suc n"
    show  "(y. (y, x)  r  y  level A r k)"
    proof-
      have "(0  k  k  n)  k = Suc n"  using hip by auto
      thus ?thesis
      proof(rule disjE)
        assume hip1:  "0  k  k  n"
        have "y. (y,x)r  y  (level A r (n+1))" 
        using `tree A r` level  `x  level A r (Suc n + 1)` by auto
        then obtain y where y1: "(y,x)r" and y2: "y  (level A r (n+1))" 
          by auto    
        have "k. 0  k  k  n  (z. (z, y)  r  z  level A r k)" 
          using y2  Suc(1-3) by auto 
        hence "(z. (z, y)  r  z  level A r k)" 
          using hip1 by auto
        then obtain z where  z1: "(z, y)  r" and z2: "z  (level A r k)" by auto
        have  "r  A × A" and "strict_part_order A r" 
          using  `tree A r` tree by auto
        hence "zA" and  "yA" and "xA"
          using `r  A × A` `(z, y)  r` `(y,x)r` by auto
        have "transitive_on A r" using `strict_part_order A r`
          by(unfold strict_part_order_def, auto)
        hence "(z, x)  r" using `zA` `yA` and `xA` `(z, y)  r` `(y,x)r`
          by(unfold transitive_on_def, blast)
        thus "(y. (y, x)  r  y  level A r k)"
          using z2 by auto
      next
        assume  "k = Suc n"
        thus  "y. (y,x)r  y  (level A r k)"
          using `tree A r` level `x  level A r (Suc n + 1)` by auto
        qed
      qed
    qed
  qed
  thus ?thesis using assms by auto
qed

lemma set_nodes_at_level:  
  assumes "tree A r"  
  shows "(level A r (n+1)) {}  (k.(0k  kn)  (level A r k) {})"
proof(rule impI) 
  assume hip:  "(level A r (n+1)) {}"
    show  "(k.(0k  kn)  (level A r k) {})"
    proof-      
      have  "x. x(level A r (n+1))" using hip by auto  
      then obtain x where x: "x(level A r (n+1))" by auto
      thus ?thesis using assms path_to_node[of A r] by blast
    qed
  qed

lemma emptyness_below_height:
  assumes  "tree A r"  
  shows  "((level A r (n+1)) = {})  (k. k>(n+1)  (level A r k) = {})"
proof(rule ccontr)
  assume hip: "¬ (level A r (n+1) = {}  (k>(n+1). level A r k = {}))"
  show False
  proof-
    have "((level A r (n+1)) = {})  ¬(k>(n+1). level A r k = {})" 
      using hip by auto
    hence 1: "(level A r (n+1)) = {}" and 2: "k>(n+1). (level A r k)  {}"
      by auto
    obtain z where z1: "z>(n+1)" and z2: "(level A r z)  {}"
      using 2 by auto
    have "z>0" using  `z>(n+1)` by auto 
    hence "(level A r ((z-1)+1))  {}"
      using z2 by simp
    hence "k.(0k  k(z-1))  (level A r k) {}" 
      using  z2 `tree A r` set_nodes_at_level[of A r "z-1"]
      by auto
    hence  "(level A r (n+1))  {}"
      using `z>(n+1)` by auto
    thus False using 1 by auto
  qed
qed

lemma characterization_nodes_tree_finite_height:
  assumes "tree A r" and "k. k>m  (level A r k) = {}"
  shows "A = (n{0..m}. level A r n)"
proof- 
  have a: "A = (n. level A r n)" using  union_levels[of A r] by auto
  have "(n. level A r n) = (n{0..m}. level A r n)"
  proof(rule equalityI)
    show "(n. level A r n)  (n{0..m}.  level A r n)"
    proof(rule subsetI)
      fix x
      assume hip: "x(n. level A r n)" 
      show "x(n{0..m}. level A r n)"
      proof-
        have "n. x level A r n"  
        using hip level_element[of A] by auto
        then obtain n where n: "x level A r n" by auto
        have "n{0..m}"
        proof(rule ccontr)
          assume 1: "n  {0..m}"
          show False
          proof-
            have "n > m" using 1 by auto
            thus False using assms(2) n by auto
          qed
        qed
        thus "x(n{0..m}. level A r n)" using n by auto
      qed
    qed
  next
    show  "(n{0..m}. level A r n)  (n. level A r n)" by auto
  qed
  thus  "A = (n{0..m}. level A r n)" using a by auto
qed

lemma finite_tree_if_fin_branches_and_fin_height:
  assumes "tree A r"  and  "finitely_branching  A r"
  and "n. (k. k>n  (level A r k) = {})"
  shows "finite A"
proof-
  obtain m where m: "(k. k>m  (level A r k) = {})" 
    using assms(3) by auto 
  hence 1: "A =(n{0..m}. level A r n)"
    using  assms(1) assms(3) characterization_nodes_tree_finite_height[of A r m] by auto
  have "n. finite (level A r n)" 
    using assms(1-2) finite_level by auto
  hence "n{0..m}. finite (level A r n)" by auto
  hence "finite (n{0..m}. level A r n)" by auto
  thus "finite A" using 1 by auto
qed

lemma all_levels_non_empty:
  assumes  "infinite_tree A r" and  "finitely_branching A r"
  shows "n. level A r n  {}"
proof(rule ccontr)
  assume hip: "¬ (n. level A r n  {})"
  show False
  proof-
    have "tree A r" using `infinite_tree A r` by auto
    have "(n. level A r n = {})" using hip by auto
    then obtain n where n: "level A r n = {}" by auto 
    thus False
    proof(cases n)
      case 0
      then show False
      proof-
        have "a. minimum A a r" using `tree A r` tree[of A r] by auto
        then obtain a where a:  "minimum A a r" by auto
        have " strict_part_order A r" 
        and "xA. finite (predecessors A x r)" 
          using  `tree A r` tree[of A r] by auto
        hence "level A r n = {a}" 
          using a `n=0` zero_level[of A r a] by auto
        thus False using `level A r n = {}` by auto
      qed
      next
        case (Suc nat)
        fix m
        assume hip: "n = Suc m" show False
        proof-
          have 1:  "level A r (Suc m) = {}"  
            using hip  n by auto
        have "(k. k>(m+1)  (level A r k) = {})" 
          using `tree A r` 1  emptyness_below_height[of A r m] by auto
        hence 1: "(n. k. k>n  (level A r k) = {})" by auto
        hence 2: "finite A" 
          using `tree A r` 1 `finitely_branching  A r` finite_tree_if_fin_branches_and_fin_height[of A r] by auto
        have 3:  "¬ finite A" using `infinite_tree A r` by auto
        show False using 2 3 by auto
      qed
    qed
  qed
qed

lemma simple_cyclefree:
  assumes "tree A r" and "(x,z)r" and "(y,z)r" and "xy" 
  shows "(x,y)r  (y,x)r"
proof-
  have "r  A × A" using `tree A r` by(unfold tree_def, auto)
  hence "xA" and  "yA" and  "zA" using  `(x,z)r` and `(y,z)r` by auto 
  hence 1: "x  predecessors A z r" and 2: "y  predecessors A z r"
    using assms by(unfold predecessors_def, auto)
  have "(total_on (predecessors A  z r) r)"
    using `tree A r` `zA` by(unfold tree_def, auto)
  thus ?thesis using 1 2 `xy`  total_on_def[of "predecessors A z r" r] by auto 
qed

lemma inclusion_predecessors:
  assumes  "r  A × A" and "strict_part_order A r" and "(x,y)r"
  shows "(predecessors A x r)  (predecessors A y r)"
proof-
  have "irreflexive_on A r" and "transitive_on A r" 
    using assms(2) by (unfold strict_part_order_def, auto) 
  have 1: "(predecessors A x r) (predecessors A y r)"
  proof(rule subsetI)
    fix z
    assume "zpredecessors A x r"
    hence "zA" and "(z,x)r" by(unfold predecessors_def, auto)
    have "xA" and "yA"  using `(x,y)r` `r  A × A` by auto
    hence "(z,y)r"
      using `zA` `yA` `xA` `(z,x)r` `(x,y)r` `transitive_on A r` 
      by (unfold transitive_on_def, blast) 
    thus "zpredecessors A y r" 
      using `zA` by(unfold predecessors_def, auto)
  qed
  have 2: "xpredecessors A y r" 
    using `r  A × A` `(x,y)r` by(unfold predecessors_def, auto)
  have 3:  "xpredecessors A x r"
  proof(rule ccontr)
    assume "¬ x  predecessors A x r"
    hence "x  predecessors A x r" by auto
    hence "xA  (x,x)r"
      by(unfold predecessors_def, auto)
    thus False using `irreflexive_on A r`
      by (unfold irreflexive_on_def, auto)
  qed
  have "(predecessors A x r)  (predecessors A y r)"
    using 2 3 by auto
  thus ?thesis using 1 by auto
qed

lemma different_height_finite_pred:
  assumes  "r  A × A" and "strict_part_order A r" and "(x,y)r" 
  and  "finite (predecessors A y r)"
  shows "height A x r < height A y r" 
proof- 
  have "card(predecessors A x r) < card(predecessors A y r)" 
    using assms  inclusion_predecessors[of r A x y] psubset_card_mono by auto
  thus ?thesis by(unfold height_def, auto)
qed

lemma different_levels_finite_pred:
  assumes  "r  A × A" and "strict_part_order A r" and "(x,y)r"
  and "x  (level A r n)"  and  "y  (level A r m)" 
  and  "finite (predecessors A y r)"
  shows "level A r n  level A r m"
proof(rule ccontr)
  assume "¬ level A r n  level A r m"
  hence "level A r n = level A r m"  by auto
  hence "x  (level A r m)"  using `x  (level A r n)` by auto
  hence 1:  "height A x r= m"  by(unfold level_def, auto)
  have "height A y r= m" using `y  (level A r m)` by(unfold level_def, auto)
  hence "height A x r = height A y r" using 1 by auto
  thus False 
    using assms different_height_finite_pred[of r A x y] by (unfold level_def, auto)
qed

lemma less_level_pred_in_fin_pred: 
  assumes  "r  A × A" and "strict_part_order A r" 
  and "x  predecessors A y r"  and "y  (level A r n)"
  and  "x  (level A r m)" 
  and "finite (predecessors A y r)"
  shows "m<n" 
proof-
  have "(x,y)r" using `(x  predecessors A y r)`
    by (unfold predecessors_def, auto)
  thus ?thesis 
    using assms  different_height_finite_pred[of r A x y] by(unfold level_def, auto)
qed

lemma emptyness_inter_diff_levels_aux:
  assumes "tree A r" and "x(predecessors A z r)" 
  and "y(predecessors A z r)"
  and  "xy" and "x  (level A r n)" and "y  (level A r m)" 
  shows "level A r n  level A r m = {}" 
proof-   
  have "(x,y)r  (y,x)r"     
    using assms simple_cyclefree[of A] by(unfold predecessors_def, auto)
  thus "level A r n  level A r m ={}"
  proof(rule disjE)
    assume  "(x, y)  r" 
    have "r A × A" and 1: "strict_part_order A r"
      using  `tree A r` by(unfold tree_def,auto)
    hence "xA" and "yA"  and  2: "x(predecessors A y r)"
      using `(x, y)  r`  by(unfold predecessors_def, auto)
    have 3: "finite (predecessors A y r)"
      using `yA`  `tree A r` by(unfold tree_def, auto) 
    hence  "n<m"
      using assms `r A × A` 1 2 3 less_level_pred_in_fin_pred[of r A x y m n]
      by auto
    hence "k>0. m=n+k" by arith
    then obtain k where k: "k>0" and m: "m=n+k" by auto
    thus ?thesis using uniqueness_level_aux[OF k, of A ]
      by auto
  next
    assume  "(y, x)  r" 
    have "r A × A" and 1: "strict_part_order A r"
      using  `tree A r` by(unfold tree_def,auto)
    hence "xA" and "yA" and 2: "y(predecessors A x r)"
      using `(y, x)  r`
      by(unfold predecessors_def, auto)
    have 3: "finite (predecessors A x r)" 
      using `xA` `tree A r`
      by(unfold tree_def, auto) 
    hence  "m<n" 
      using assms `r A × A` 1 2 3 less_level_pred_in_fin_pred[of r A y x n m]
      by auto
    hence "k>0. n=m+k" by arith
    then obtain k where k: "k>0" and m: "n=m+k" by auto
    thus ?thesis using  uniqueness_level_aux[OF k, of A] by auto
  qed
qed

lemma emptyness_inter_diff_levels:
  assumes "tree A r" and "(x,z) r" and "(y,z) r"
  and  "xy" and  "x  (level A r n)" and "y  (level A r m)" 
shows "level A r n  level A r m = {}" 
proof-
  have "r  A × A"  using  `tree A r` tree by auto
  hence "xA" and  "yA"  using  `r  A × A`  `(x,z)  r`  `(y,z)r` by auto
  hence "x(predecessors A z r)" and "y(predecessors A z r)" 
    using  `(x,z) r` and `(y,z) r` by(unfold predecessors_def, auto)
  thus ?thesis
    using assms  emptyness_inter_diff_levels_aux[of A r] by blast
qed

primrec disjunction_nodes :: "'a list   'a formula"  where
 "disjunction_nodes [] = FF"   
| "disjunction_nodes (v#D) = (atom v) ∨. (disjunction_nodes D)"

lemma truth_value_disjunction_nodes:
  assumes "v set l" and "t_v_evaluation I (atom v) = Ttrue"
  shows "t_v_evaluation I (disjunction_nodes l) = Ttrue"
proof-
  have "v set l   t_v_evaluation I (atom v) = Ttrue 
  t_v_evaluation I (disjunction_nodes l) = Ttrue" 
  proof(induct l)
    case Nil
    then show ?case by auto
  next
    case (Cons a l)
    then show  "t_v_evaluation I (disjunction_nodes (a # l)) = Ttrue"
    proof-
      have "v = a  va" by auto
      thus  "t_v_evaluation I (disjunction_nodes (a # l)) = Ttrue"
      proof(rule disjE)
        assume "v = a"
        hence 1: "disjunction_nodes (a#l) = (atom v) ∨. (disjunction_nodes l)"
          by auto 
        have "t_v_evaluation I ((atom v) ∨. (disjunction_nodes l)) = Ttrue"  
          using Cons(3)  by(unfold t_v_evaluation_def,unfold v_disjunction_def, auto)
        thus ?thesis using 1  by auto
      next
        assume "v  a"
        hence "v set l" using Cons(2) by auto
        hence "t_v_evaluation I (disjunction_nodes l) = Ttrue"
          using Cons(1) Cons(3) by auto
        thus ?thesis
          by(unfold t_v_evaluation_def,unfold v_disjunction_def, auto)
      qed
    qed
  qed
  thus ?thesis using assms by auto
qed

lemma set_set_to_list1:
  assumes "tree A r" and  "finitely_branching A r" 
  shows "set (set_to_list (level A r n)) = (level A r n)"
  using assms finite_level[of A r n]  set_set_to_list by auto

lemma truth_value_disjunction_formulas:
  assumes  "tree A r" and  "finitely_branching A r"
  and  "v(level A r n)  t_v_evaluation I (atom v) = Ttrue" 
  and  "F = disjunction_nodes(set_to_list (level A r n))" 
  shows "t_v_evaluation I  F = Ttrue"
proof- 
  have "set (set_to_list (level A r n)) = (level A r n)" 
    using set_set_to_list1 assms(1-2) by auto
  hence "v set (set_to_list (level A r n))"
    using assms(3) by auto
  thus "t_v_evaluation I F = Ttrue"
    using assms(3-4) truth_value_disjunction_nodes by auto
qed

definition  :: "'a set  'a rel  ('a formula) set"  where
   " A r   (n. {disjunction_nodes(set_to_list (level A r n))})"

definition 𝒢 ::  "'a set  'a rel  ('a formula) set"  where
   "𝒢 A r  {(atom u) →. (atom v) |u v. uA  vA  (v,u) r}" 

definition ℋn :: "'a set  'a rel  nat  ('a formula) set"  where
   "ℋn A r n  {¬.((atom u) ∧. (atom v))
                         |u v . u(level A r n)  v(level A r n)  uv }"
definition   :: "'a set  'a rel  ('a formula) set"  where
 " A r   n. ℋn A r n"

definition 𝒯 :: "'a set  'a rel  ('a formula) set"  where
   "𝒯 A r   ( A r)  (𝒢 A r)  ( A r)" 

primrec nodes_formula :: "'v formula   'v set" where
  "nodes_formula FF = {}"
| "nodes_formula TT = {}"
| "nodes_formula (atom P) =  {P}"
| "nodes_formula (¬. F) = nodes_formula F"
| "nodes_formula (F ∧. G) = nodes_formula F  nodes_formula G"
| "nodes_formula (F ∨. G) = nodes_formula F  nodes_formula G"
| "nodes_formula (F →.G) = nodes_formula F  nodes_formula G"

definition nodes_set_formulas :: "'v formula set   'v set"  where
"nodes_set_formulas S = (F S. nodes_formula F)"

definition maximum_height:: "'v set 'v rel  'v  formula  set    nat"  where
 "maximum_height A r S =  Max (xnodes_set_formulas S. {height A x r})"

lemma node_formula:
  assumes "v  set l" 
  shows "v  nodes_formula (disjunction_nodes l)" 
proof-
  have "v  set l  v  nodes_formula (disjunction_nodes l)" 
  proof(induct l)
    case Nil
    then show ?case by auto
  next
    case (Cons a l)  
    show "v  nodes_formula (disjunction_nodes (a # l))"  
   proof-
     have "v = a  va" by auto
     thus "v  nodes_formula (disjunction_nodes (a # l))"
     proof(rule disjE)
       assume "v = a"
       hence 1: "disjunction_nodes (a#l) = (atom v) ∨. (disjunction_nodes l)"
         by auto 
       have "v  nodes_formula ((atom v) ∨. (disjunction_nodes l))" by auto 
       thus ?thesis using 1  by auto
     next
       assume "v  a"
       hence "v set l" using Cons(2) by auto
       hence "v  nodes_formula (disjunction_nodes l)"
         using Cons(1) Cons(2) by auto
       thus ?thesis by auto
     qed
   qed
 qed
  thus ?thesis using assms by auto
qed 

lemma node_disjunction_formulas:
  assumes  "tree A r" and  "finitely_branching A r" and "v(level A r n)" 
  and  "F = disjunction_nodes(set_to_list (level A r n))" 
  shows  "v  nodes_formula F"
proof- 
  have "set (set_to_list (level A r n)) = (level A r n)" 
    using set_set_to_list1 assms(1-2) by auto
  hence "v set (set_to_list (level A r n))" 
    using assms(3) by auto
  thus "v  nodes_formula F"
    using assms(3-4)  node_formula  by auto
qed

fun node_sig_level_max:: "'v set  'v rel  'v formula set   'v" 
  where "node_sig_level_max A r S = 
  (SOME u. u  (level A r ((maximum_height A r S)+1)))"

lemma node_level_maximum:  
  assumes "infinite_tree A r" and  "finitely_branching A r"
  shows "(node_sig_level_max A r S)   (level A r ((maximum_height A r S)+1))" 
proof-
  have  "u. u  (level A r ((maximum_height A r S)+1))"
    using assms  all_levels_non_empty[of A r] by (unfold level_def, auto)
  then obtain u where u: "u  (level A r (( maximum_height A r S)+1))" by auto
  hence "(SOME u. u  (level A r ((maximum_height A r S)+1)))  (level A r ((maximum_height A r S)+1))" 
    using someI by auto
  thus ?thesis by auto 
qed

fun path_interpretation :: "'v set 'v rel  'v  ('v    v_truth)"  where
"path_interpretation A r u = (λv. (if (v,u)r  then Ttrue else Ffalse))"

lemma finiteness_nodes_formula:
 "finite (nodes_formula F)" by(induct F, auto)

lemma finiteness_set_nodes:
  assumes "finite S" 
  shows  "finite (nodes_set_formulas S)" 
  using assms finiteness_nodes_formula 
  by (unfold nodes_set_formulas_def, auto)

lemma maximum1:
  assumes  "finite S" and "u  nodes_set_formulas S"
  shows "(height A u r)   (maximum_height A r S)" 
proof-  
  have "(height A u r)  ( xnodes_set_formulas S. {height A x r})" 
    using assms(2) by auto
  thus "(height A u r)   (maximum_height A r S)"
    using `finite S` finiteness_set_nodes[of S] 
    by(unfold maximum_height_def, auto) 
qed

lemma value_path_interpretation:
  assumes "t_v_evaluation (path_interpretation A r v) (atom u) = Ttrue"
  shows "(u,v)r"
proof(rule ccontr)
  assume "(u, v)  r"
  hence "t_v_evaluation (path_interpretation A r v) (atom u) = Ffalse"
    by(unfold t_v_evaluation_def, auto) 
  thus False using assms by auto
qed

lemma satisfiable_path:
  assumes "infinite_tree A r"
  and  "finitely_branching A r" and  "S  (𝒯 A r)" 
  and "finite S" 
shows  "satisfiable S"
proof-
  let ?m = "(maximum_height A r S)+1"
  let ?level = "level A r ?m"
  let ?u = "node_sig_level_max A r S" 
  have 1: "tree A r" using `infinite_tree A r` by auto
  have  "r  A × A" and "strict_part_order A r" 
    using  `tree A r` tree by auto
  have "transitive_on A r" 
    using `strict_part_order A r`
    by(unfold strict_part_order_def, auto) 
  have "u. u ?level" 
    using assms(1-2) node_level_maximum by auto
  then obtain u where u: "u  ?level"  by auto
  hence levelu:  "?u  ?level"
    using someI by auto
  hence "?uA" by(unfold level_def, auto)
  have "(path_interpretation A r ?u) model S"
  proof(unfold model_def)
    show "FS. t_v_evaluation (path_interpretation A r ?u) F = Ttrue"
    proof 
      fix F assume "F  S"
      show  "t_v_evaluation (path_interpretation A r ?u) F  = Ttrue"
      proof-        
        have "F  ( A r)  (𝒢 A r)  ( A r)" 
        using `S   𝒯 A r` `F  S` assms(2)  by(unfold 𝒯_def,auto) 
        hence  "F  ( A r)  F  (𝒢 A r)  F  ( A r)" by auto 
        thus ?thesis
        proof(rule disjE)
          assume "F  ( A r)"
          hence "n. F = disjunction_nodes(set_to_list (level A r n))" 
            by(unfold ℱ_def,auto)
          then obtain n
            where n: "F = disjunction_nodes(set_to_list (level A r n))" 
            by auto
          have "v. v(level A r n)" 
            using  assms(1-2) all_levels_non_empty[of A r] by auto 
          then obtain v where v: "v  (level A r n)" by auto      
          hence  "v  nodes_formula F" 
            using n node_disjunction_formulas[OF 1 assms(2) v, of F ]
            by auto
          hence a: "v  nodes_set_formulas S" 
            using `F  S`  by(unfold nodes_set_formulas_def, blast)
          hence b: "(height A v r)  (maximum_height A r S)" 
            using `finite S`  maximum1[of S v] by auto
          have "(height A v r) = n" 
            using v by(unfold level_def, auto) 
          hence  "n < ?m" 
            using `finite S` a   maximum1[of S v A r]
            by(unfold maximum_height_def, auto)         
          hence "(y. (y,?u)r  y  (level A r n))" 
            using levelu `tree A r` path_to_node[of A r]
            by auto
          then obtain y where y1: "(y,?u)r" and y2: "y  (level A r n)"
            by auto
          hence "t_v_evaluation (path_interpretation A r ?u) (atom y) = Ttrue" 
            by auto
          thus "t_v_evaluation (path_interpretation A r ?u) F = Ttrue"
            using 1 assms(2) y2 n  truth_value_disjunction_formulas[of A r y]
            by auto
        next
          assume  "F  𝒢 A r  F   A r"
          thus "t_v_evaluation (path_interpretation A r ?u) F = Ttrue"
          proof(rule disjE)
            assume  "F  𝒢 A r"
            hence "u. v. uA  vA   (v,u) r  
                  (F = (atom u) →. (atom v))"
              by (unfold  𝒢_def, auto)
            then obtain u v where "uA" and "vA" and "(v,u) r" 
            and F: "(F = (atom u) →. (atom v))" by auto
            show "t_v_evaluation (path_interpretation A r ?u) F = Ttrue"  
            proof(rule ccontr)
              assume "¬(t_v_evaluation (path_interpretation A r ?u) F = Ttrue)" 
              hence "t_v_evaluation (path_interpretation A r ?u) F = Ffalse"
                using Bivaluation by auto
              hence "t_v_evaluation (path_interpretation A r ?u) (atom u) =  Ttrue 
              t_v_evaluation (path_interpretation A r ?u) (atom v) =  Ffalse" 
                using F  eval_false_implication by blast
              hence 1: "t_v_evaluation (path_interpretation A r ?u) (atom u) =  Ttrue"
              and   2: "t_v_evaluation (path_interpretation A r ?u) (atom v) =  Ffalse"
                by auto
              have "(u,?u)r" using 1 value_path_interpretation by auto
              hence "(v,?u) r" 
                using  `uA` `vA` `?uA` `(v,u) r` `transitive_on A r` 
                by(unfold transitive_on_def, blast)
              hence "t_v_evaluation (path_interpretation A r ?u) (atom v) =  Ttrue" 
                by auto
              thus False using 2 by auto
            qed
          next
            assume  "F   A r" 
            hence "n. F  ℋn A r n" by(unfold  ℋ_def, auto)
            then obtain n where  "F  ℋn A r n" by auto
            hence
            "u. v. F = ¬.((atom u) ∧. (atom v))  u(level A r n) 
             v(level A r n)  uv"
              by(unfold ℋn_def, auto)  
            then obtain u v where F: "F = ¬.((atom u) ∧. (atom v))" 
            and "u(level A r n)" and "v(level A r n)" and "uv"
              by auto
            show "t_v_evaluation (path_interpretation A r ?u) F = Ttrue"  
            proof(rule ccontr)
              assume "t_v_evaluation (path_interpretation A r ?u) F  Ttrue"
              hence "t_v_evaluation (path_interpretation A r ?u) F = Ffalse"
                using Bivaluation by auto
              hence
              "t_v_evaluation (path_interpretation A r ?u)((atom u) ∧.
               (atom v)) = Ttrue" 
                using F  NegationValues1 by blast
              hence "t_v_evaluation (path_interpretation A r ?u)(atom u) = Ttrue 
              t_v_evaluation (path_interpretation A r ?u)(atom v) = Ttrue"
                using ConjunctionValues by blast
              hence "(u,?u)r" and  "(v,?u)r"
                using  value_path_interpretation by auto
              hence a: "(level A r n)  (level A r n) = {}"
                using `tree A r`  `u(level A r n)`  `v(level A r n)`  `uv`
                emptyness_inter_diff_levels[of A r]
                by blast
              have "(level A r n)  {}" 
                using  `v(level A r n)` by auto           
              thus False using a by auto 
            qed
          qed
        qed
      qed
    qed
  qed
  thus "satisfiable S" by(unfold satisfiable_def, auto)
qed

definition :: "'a set  ('a   v_truth)  'a set" where
" A I   {u|u. uA  t_v_evaluation I (atom u) = Ttrue}"

lemma value_disjunction_list1:
  assumes "t_v_evaluation I (disjunction_nodes (a # l)) = Ttrue"
  shows "t_v_evaluation I (atom a) = Ttrue  t_v_evaluation I (disjunction_nodes l) = Ttrue" 
proof-
  have "disjunction_nodes (a # l) = (atom a) ∨. (disjunction_nodes l)"
    by auto
  hence "t_v_evaluation I ((atom a) ∨. (disjunction_nodes l)) = Ttrue" 
    using assms by auto
  thus ?thesis using DisjunctionValues by blast
qed

lemma value_disjunction_list:
  assumes "t_v_evaluation I (disjunction_nodes l) = Ttrue"
  shows "x. x  set l  t_v_evaluation I (atom x) = Ttrue" 
proof-
  have "t_v_evaluation I (disjunction_nodes l) = Ttrue 
  x. x  set l   t_v_evaluation I (atom x) = Ttrue" 
  proof(induct l)
    case Nil
    then show ?case by auto
  next   
    case (Cons a l)  
    show  "x. x  set (a # l)  t_v_evaluation I (atom x) = Ttrue"  
    proof-
      have "t_v_evaluation I (atom a) = Ttrue  t_v_evaluation I (disjunction_nodes l)=Ttrue" 
        using Cons(2) value_disjunction_list1[of I] by auto      
      thus ?thesis
    proof(rule disjE)
      assume "t_v_evaluation I (atom a) = Ttrue"
      thus ?thesis by auto
    next
      assume "t_v_evaluation I (disjunction_nodes l) = Ttrue" 
      thus ?thesis
        using Cons by auto    
    qed
  qed
qed
  thus ?thesis using assms by auto
qed 

lemma intersection_branch_set_nodes_at_level:
  assumes "infinite_tree A r" and "finitely_branching A r" 
  and I: "F  ( A r). t_v_evaluation I F = Ttrue"
shows "n. x. x  level A r n  x  ( A I)" using all_levels_non_empty
proof- 
  fix n 
  have "n. t_v_evaluation I (disjunction_nodes(set_to_list (level A r n))) = Ttrue"
    using I by (unfold ℱ_def, auto)
  hence 1:
  "n. x. x  set (set_to_list (level A r n))  t_v_evaluation I (atom x) = Ttrue"
    using value_disjunction_list by auto
  have "tree A r" 
    using `infinite_tree A r`by auto
  hence "n. set (set_to_list (level A r n)) = level A r n" 
    using assms(1-2)  set_set_to_list1 by auto
  hence  "n. x. x  level A r n   t_v_evaluation I (atom x) = Ttrue"
    using 1  by auto
  hence  "n. x. x  level A r n  xA  t_v_evaluation I (atom x) = Ttrue" 
    by(unfold level_def, auto)
  thus ?thesis using ℬ_def[of A I] by auto
qed

lemma intersection_branch_emptyness_below_height:
  assumes I:  "F  ( A r). t_v_evaluation I F = Ttrue" 
  and "x( A I)"  and  "y( A I)"  and  "x  y" and  n: "x  level A r n"
  and m: "y  level A r m" 
shows  "n  m"
proof(rule ccontr)
  assume "¬ n  m"
  hence "n=m" by auto
  have "xA" and  "yA" and v1: "t_v_evaluation I (atom x) = Ttrue" 
  and v2: "t_v_evaluation I (atom y) = Ttrue" 
    using  `x( A I)` `y( A I)`  by(unfold ℬ_def, auto) 
  have "¬.((atom x) ∧. (atom y))  (ℋn A r n)" 
    using `xA`   `yA`  `x  y` n m `n=m`
    by(unfold ℋn_def, auto)             
  hence "¬.((atom x) ∧. (atom y))  ( A r)"
    by(unfold ℋ_def, auto)                   
  hence "t_v_evaluation I (¬.((atom x) ∧. (atom y))) = Ttrue"
    using I by auto
  moreover                  
  have "t_v_evaluation I ((atom x) ∧. (atom y)) = Ttrue"
    using v1 v2 v_conjunction_def by auto
  hence "t_v_evaluation I (¬.((atom x) ∧. (atom y))) = Ffalse" 
    using v_negation_def by auto 
  ultimately
  show False by auto
qed

lemma intersection_branch_level: 
  assumes  "infinite_tree A r" and "finitely_branching A r" 
  and I: "F  ( A r)  ( A r). t_v_evaluation I F = Ttrue"
shows "n. u. ( A I)   level A r n = {u}"
proof
  fix n 
  show "u. ( A I)  level A r n = {u}" 
  proof-
    have "u. u  level A r n  u  ( A I)" 
      using assms intersection_branch_set_nodes_at_level[of A r I] by auto
    then obtain u where u: "u  level A r n  u( A I)" by auto
    hence 1:  "{u}  ( A I)  level A r n" by blast
    have 2:  "( A I)  level A r n  {u}"
    proof(rule subsetI)
      fix x
      assume  "x( A I)  level A r n"
      hence 2: "x( A I)  x level A r n"  by auto
      have "u = x"
      proof(rule ccontr)
        assume "u  x"
        hence "nn" 
          using u 2 I intersection_branch_emptyness_below_height[of A r] by blast
        thus False by auto
      qed
      thus "x{u}" by auto
    qed
    have "( A I)  level A r n = {u}"
      using 1 2 by auto
    thus "u.( A I)   level A r n = {u}"  by auto
  qed
qed

lemma predecessor_in_branch:
  assumes I:  "F  (𝒢 A r). t_v_evaluation I F = Ttrue" 
  and "y( A I)"  and  "(x,y) r" and "xA" and "yA"
shows "x( A I)"
proof- 
  have "(atom y) →. (atom x) 𝒢 A r" 
    using `xA`  `yA`  `(x, y)r` by (unfold  𝒢_def, auto)
  hence "t_v_evaluation I ((atom y) →. (atom x)) = Ttrue"
    using I by auto
  moreover
  have "t_v_evaluation I (atom y) = Ttrue" 
    using  `y( A I)` by(unfold ℬ_def, auto)
  ultimately
  have "t_v_evaluation I (atom x) = Ttrue"
    using v_implication_def by  auto
  thus  "x( A I)" using  `xA`  by(unfold ℬ_def, auto) 
qed

lemma is_path: 
  assumes  "infinite_tree A r" and "finitely_branching A r" 
  and I: "F  (𝒯 A r). t_v_evaluation I F = Ttrue" 
shows "path ( A I) A r"
proof(unfold path_def)
  let ?B = "( A I)" 
  have "tree A r" 
  using  `infinite_tree A r` by auto
  have "F  ( A r)  (𝒢 A r)  ( A r). t_v_evaluation I F = Ttrue"
    using I by(unfold 𝒯_def)
  hence I1:  "F  ( A r). t_v_evaluation I F = Ttrue" 
  and   I2:  "F  (𝒢 A r). t_v_evaluation I F = Ttrue"
  and   I3:  "F  ( A r). t_v_evaluation I F = Ttrue" 
    by auto 
  have 0: "sub_linear_order ?B A r"
  proof(unfold sub_linear_order_def)
    have 1: "?B  A"  by(unfold ℬ_def, auto)
    have 2: "strict_part_order A r" 
      using `tree A r` tree[of A r] by auto
    have "total_on ?B r"
    proof(unfold total_on_def)
      show "x?B. y?B. x  y  (x, y)  r  (y, x)  r"
      proof
        fix x
        assume "x?B" 
        show "y?B. x  y  (x, y)  r  (y, x)  r"
        proof              
          fix y
          assume "y?B"
          show "x  y  (x, y)  r  (y, x)  r" 
          proof(rule impI)
            assume "x  y" 
            have "xA" and "yA" and v1: "t_v_evaluation I (atom x) = Ttrue" 
            and v2: "t_v_evaluation I (atom y) = Ttrue" 
              using `x?B` `y?B`  by(unfold ℬ_def, auto)
            have "(n. x  level A r n)" and "(m. y  level A r m)" 
              using `xA` and `yA` level_element[of A r]
              by auto
            then obtain n m
            where n: "x  level A r n" and m: "y  level A r m"
              by auto             
            have "nm"
              using I3 `x?B` `y?B` `x  y` n m 
                    intersection_branch_emptyness_below_height[of A r]
              by auto                
            hence "n<m  m<n" by auto
            thus "(x, y)  r  (y, x)  r" 
            proof(rule disjE)
              assume  "n < m"  
              have "(x, y)  r"
              proof(rule ccontr)
                assume "(x, y)  r"
                have "z. (z, y)r  z  level A r n" 
                  using `tree A r` `y  level A r m` `n < m`
                         path_to_node[of A r y "m-1"]
                  by auto 
                then obtain z where z1: "(z, y)r" and z2: "z  level A r n"
                  by auto 
                have "zA" using  `tree A r` tree z1 by auto
                hence "z( A I)" 
                  using I2 `yA` `y?B` `(z, y)r` predecessor_in_branch[of A r I y z]
                  by auto
                have "xz" using `(x, y)  r` `(z, y)r` by auto  
                hence "nn"
                  using I3 `x?B` `z?B` n z2  intersection_branch_emptyness_below_height[of A r]
                  by blast  
                thus False by auto 
              qed
              thus "(x, y)  r  (y, x)  r" by auto
            next
              assume "m < n"
              have "(y, x)  r"
              proof(rule ccontr)
                assume "(y, x)  r"
                have "z. (z, x)r  z  level A r m" 
                  using `tree A r`  `x  level A r n`  `m < n`
                         path_to_node[of A r x "n-1"]
                  by auto 
                  then obtain z where z1: "(z, x)r" and z2: "z  level A r m"
                  by auto 
                have "zA" using  `tree A r` tree z1 by auto
                hence  "z( A I)" 
                  using I2 `xA` `x?B` `(z, x)r` predecessor_in_branch[of A r I x z]
                  by auto
                have "yz" using `(y, x)  r` `(z, x)r` by auto  
                hence "mm"
                  using I3 `y?B` `z?B` m z2 intersection_branch_emptyness_below_height[of A r ]
                  by blast
                thus False by auto 
              qed
              thus "(x, y)  r  (y, x)  r" by auto
            qed
          qed
        qed
      qed
    qed
    thus 3: "?B  A  strict_part_order A r  total_on ?B r"
      using 1 2 by auto             
  qed             
  have 4: "(C. ?B  C  sub_linear_order C A r  ?B = C)"               
  proof
    fix C
    show "?B  C  sub_linear_order C A r  ?B = C"
    proof(rule impI)
      assume "?B  C  sub_linear_order C A r"
      hence "?B  C" and  "sub_linear_order C A r" by auto
      have "C  ?B"           
      proof(rule subsetI)
          fix x
          assume "x C"
        have "C  A"
          using `sub_linear_order C A r`
         by(unfold sub_linear_order_def, auto)
        hence "xA" using `xC` by auto
        have "n. xlevel A r n" 
          using `xA` level_element[of A] by auto
        then obtain n where n: "xlevel A r n" by auto
        have "u. ( A I)  level A r n = {u}"
          using assms(1,2) I1 I3 intersection_branch_level[of A r]
          by blast
        then obtain u where i: "( A I)  level A r n = {u}" 
          by auto
        hence "uA" and u: "u  level A r n"
         by(unfold level_def, auto)
        have "x=u" 
        proof(rule ccontr)               
          assume hip: "xu" 
          have "u( A I)" using i by auto
          hence "uC" using `?B  C` by auto
          have "total_on C r"
            using `sub_linear_order C A r` sub_linear_order_def[of C A r]
            by blast         
          hence "(x,u)r  (u,x)r" 
            using hip `xC` `uC` `sub_linear_order C A r`
            by(unfold total_on_def,auto)
          thus False
          proof(rule disjE)
            assume "(x,u)r"               
            have "r  A × A" and "strict_part_order A r" 
            and "finite (predecessors A u r)"
              using `uA` `tree A r` tree[of A r] by auto
            hence  "(level A r n)  (level A r n)" 
              using `(x,u)r` `x  level A r n` `u  level A r n` 
                    different_levels_finite_pred[of r A ] by blast
            thus False by auto
          next
            assume "(u,x)r"               
            have "r  A × A" and "strict_part_order A r" 
            and "finite (predecessors A x r)"
              using `xA` `tree A r` tree[of A r]  by auto
            hence "(level A r n)  (level A r n)" 
              using `(u,x)r` `u  level A r n` `x  level A r n`
                    different_levels_finite_pred[of r A ] by blast
            thus False by auto
          qed
        qed          
        thus "x  ?B" using i by auto
      qed
      thus  "?B = C"  using `?B  C` by blast
    qed
  qed
  thus "sub_linear_order ( A I) A r 
          (C.  A I  C  sub_linear_order C A r   A I = C)"
    using `sub_linear_order ( A I) A r` by auto
qed

lemma surjective_infinite:
  assumes  "f:: 'a  nat. n. xA. n = f(x)"
  shows "infinite A"
proof(rule ccontr)
  assume "¬ infinite A"
  hence "finite A" by auto
  hence "n. g. A = g ` {i::nat. i < n}"
    using finite_imp_nat_seg_image_inj_on[of A] by auto 
  then obtain n g where g: "A = g ` {i::nat. i < n}" by auto
  obtain f where  "(n. xA. n = (f:: 'a   nat)(x))" 
    using assms by auto
  hence "m. k{i::nat. i < n}. m =(f  g)(k)"
    using g  by auto
  hence  "(UNIV :: nat set)  = (f  g) ` {i::nat. i < n}"
    by blast
  hence  "finite (UNIV :: nat set)" 
    using nat_seg_image_imp_finite by blast 
  thus False by auto
qed

lemma family_intersection_infinita:
  fixes P :: " nat  'a set"
  assumes "n. m. n  m  P n  P m = {}" 
  and  "n. (A  (P n))  {}"
  shows "infinite (n. (A  (P n)))" 
proof-
  let ?f = "λx. SOME n. x(A  (P n))"
  have "n. x(n. (A  (P n))). n = ?f(x)"
  proof
    fix n
    obtain a where a:  "a  (A  (P n))" using assms(2) by auto
    {fix m
    have  "a  (A  (P m))  m=n" 
    proof(rule impI)
      assume hip: "a  A  P m" show "m =n"
      proof(rule ccontr)
        assume "m  n"
        hence "P m  P n = {}" using assms(1) by auto
        thus False using a hip by auto
      qed
    qed}
    hence "m. a  A  P m  m = n" by auto
    hence 1: "?f(a) = n"  using a  some_equality by auto
    have "a(n. (A  (P n)))" using a by auto
    thus "xn. A  P n. n = (SOME n. x  A  P n)" using 1 by auto
  qed
  hence  "f:: 'a   nat. n. x((n. (A  (P n)))). n = f(x)" 
    using exI  by auto
  thus ?thesis using surjective_infinite by auto
qed

lemma infinite_path:
  assumes  "infinite_tree A r" and  "finitely_branching A r"
  and  I: "F  ( A r). t_v_evaluation I F = Ttrue"
shows "infinite ( A I)"
proof-
  have a: "n. m.  n  m  level A r n  level A r m = {}"
    using uniqueness_level[of _ _ A r] by auto 
  have  "n.  A I  level A r n  {}"
    using `infinite_tree A r`
          `finitely_branching A r` I  intersection_branch_set_nodes_at_level[of A r]
    by blast  
  hence  "infinite (n. ( A I)   level A r n)"
    using family_intersection_infinita  a  by auto
  thus "infinite ( A I)"by auto 
qed

theorem Koenig_Lemma:
  assumes  "infinite_tree (A::'nodes:: countable set) r" 
  and "finitely_branching A r" 
  shows  "B. infinite_path B A r"
proof-
  have  "satisfiable (𝒯 A r)" 
  proof- 
    have " S. S  (𝒯 A r)  (finite S)  satisfiable S" 
      using `infinite_tree A r` `finitely_branching A r` satisfiable_path
      by auto   
    thus "satisfiable (𝒯 A r)"
      using Compactness_Theorem[of "(𝒯 A r)"] by auto
  qed
  hence "I. (F  (𝒯 A r). t_v_evaluation I F = Ttrue)" 
    by(unfold satisfiable_def, unfold model_def, auto) 
  then obtain I where I:  "F  (𝒯 A r). t_v_evaluation I F = Ttrue"  
    by auto
  hence "F  ( A r)  (𝒢 A r)  ( A r). t_v_evaluation I F = Ttrue"
    by(unfold 𝒯_def)
  hence I1:  "F  ( A r). t_v_evaluation I F = Ttrue" 
  and   I2:  "F  (𝒢 A r). t_v_evaluation I F = Ttrue"
  and   I3:  "F  ( A r). t_v_evaluation I F = Ttrue" 
    by auto 
  let ?B = "( A I)"
  have "infinite_path ?B A r"
  proof(unfold infinite_path_def)
    show "path ?B A r  infinite ?B" 
    proof(rule conjI)
      show "path ?B A r"
        using  `infinite_tree A r` `finitely_branching A r` I is_path[of A r]
        by auto   
      show "infinite ( A I)"
        using `infinite_tree A r` `finitely_branching A r` I1 infinite_path
      by auto     
    qed
  qed
  thus "B. infinite_path B A r" by auto
qed
           
end