text‹Sometimes it is nice to think of @{typ bool}s as directions in a binary tree›
hide_const (open) Left Right type_synonym dir = bool definition Left :: bool where"Left = True" definition Right :: bool where"Right = False" declare Left_def [simp] declare Right_def [simp]
datatype tree =
Leaf
| Branching (ltree: tree) (rtree: tree)
subsection‹Sizes›
fun treesize :: "tree ==> nat"where "treesize Leaf = 0"
| "treesize (Branching l r) = 1 + treesize l + treesize r"
lemma treesize_Leaf: assumes"treesize T = 0" shows"T = Leaf" using assms by (cases T) auto
lemma treesize_Branching: assumes"treesize T = Suc n" shows"∃l r. T = Branching l r" using assms by (cases T) auto
subsection‹Paths›
fun path :: "dir list ==> tree ==> bool"where "path [] T ⟷ True"
| "path (d#ds) (Branching T1 T2) ⟷ (if d then path ds T1 else path ds T2)"
| "path _ _ ⟷ False"
lemma path_inv_Leaf: "path p Leaf ⟷ p = []" by (induction p) auto
lemma path_inv_Cons: "path (a#ds) T ⟶ (∃l r. T=Branching l r)" by (cases T) (auto simp add: path_inv_Leaf)
lemma path_inv_Branching_Left: "path (Left#p) (Branching l r) ⟷ path p l" using Left_def Right_def path.cases by (induction p) auto
lemma path_inv_Branching_Right: "path (Right#p) (Branching l r) ⟷ path p r" using Left_def Right_def path.cases by (induction p) auto
lemma path_inv_Branching: "path p (Branching l r) ⟷ (p=[] ∨ (∃a p'. p=a#p'∧ (a ⟶ path p' l) ∧ (¬a ⟶ path p' r)))" (is"?L ⟷ ?R") proof assume ?L thenshow ?R by (induction p) auto next assume r: ?R thenshow ?L proof assume"p = []"thenshow ?L by auto next assume"∃a p'. p=a#p'∧ (a ⟶ path p' l) ∧ (¬a ⟶ path p' r)" thenobtain a p' where"p=a#p'∧ (a ⟶ path p' l) ∧ (¬a ⟶ path p' r)"by auto thenshow ?L by (cases a) auto qed qed
lemma path_prefix: assumes"path (ds1@ds2) T" shows"path ds1 T" using assms proof (induction ds1 arbitrary: T) case (Cons a ds1) thenhave"∃l r. T = Branching l r"using path_inv_Leaf by (cases T) auto thenobtain l r where p_lr: "T = Branching l r"by auto show ?case proof (cases a) assume atrue: "a" thenhave"path ((ds1) @ ds2) l"using p_lr Cons(2) path_inv_Branching by auto thenhave"path ds1 l"using Cons(1) by auto thenshow"path (a # ds1) T"using p_lr atrue by auto next assume afalse: "¬a" thenhave"path ((ds1) @ ds2) r"using p_lr Cons(2) path_inv_Branching by auto thenhave"path ds1 r"using Cons(1) by auto thenshow"path (a # ds1) T"using p_lr afalse by auto qed next case (Nil) thenshow ?caseby auto qed
subsection‹Branches›
fun branch :: "dir list ==> tree ==> bool"where "branch [] Leaf ⟷ True"
| "branch (d # ds) (Branching l r) ⟷ (if d then branch ds l else branch ds r)"
| "branch _ _ ⟷ False"
lemma has_branch: "∃b. branch b T" proof (induction T) case (Leaf) have"branch [] Leaf"by auto thenshow ?caseby blast next case (Branching T1 T2) thenobtain b where"branch b T1"by auto thenhave"branch (Left#b) (Branching T1 T2)"by auto thenshow ?caseby blast qed
lemma branch_inv_Leaf: "branch b Leaf ⟷ b = []" by (cases b) auto
lemma branch_inv_Branching_Left: "branch (Left#b) (Branching l r) ⟷ branch b l" by auto
lemma branch_inv_Branching_Right: "branch (Right#b) (Branching l r) ⟷ branch b r" by auto
lemma branch_inv_Branching: "branch b (Branching l r) ⟷ (∃a b'. b=a#b'∧ (a ⟶ branch b' l) ∧ (¬a ⟶ branch b' r))" by (induction b) auto
lemma branch_inv_Leaf2: "T = Leaf ⟷ (∀b. branch b T ⟶ b = [])" proof -
{ assume"T=Leaf" thenhave"∀b. branch b T ⟶ b = []"using branch_inv_Leaf by auto
} moreover
{ assume"∀b. branch b T ⟶ b = []" thenhave"∀b. branch b T ⟶¬(∃a b'. b = a # b')"by auto thenhave"∀b. branch b T ⟶¬(∃l r. branch b (Branching l r))" using branch_inv_Branching by auto thenhave"T=Leaf"using has_branch[of T] by (metis branch.elims(2))
} ultimatelyshow"T = Leaf ⟷ (∀b. branch b T ⟶ b = [])"by auto qed
lemma branch_is_path: assumes"branch ds T" shows"path ds T" using assms proof (induction T arbitrary: ds) case Leaf thenhave"ds = []"using branch_inv_Leaf by auto thenshow ?caseby auto next case (Branching T1 T2) thenobtain a b where ds_p: "ds = a # b ∧ (a ⟶ branch b T1) ∧ (¬ a ⟶ branch b T2)"using branch_inv_Branching[of ds] by blast thenhave"(a ⟶ path b T1) ∧ (¬a ⟶ path b T2)"using Branching by auto thenshow"?case"using ds_p by (cases a) auto qed
lemma Branching_Leaf_Leaf_Tree: assumes"T = Branching T1 T2" shows"(∃B. branch (B@[True]) T ∧ branch (B@[False]) T)" using assms proof (induction T arbitrary: T1 T2) case Leaf thenshow ?caseby auto next case (Branching T1' T2')
{ assume"T1'=Leaf ∧ T2'=Leaf" thenhave"branch ([] @ [True]) (Branching T1' T2') ∧ branch ([] @ [False]) (Branching T1' T2')"by auto thenhave ?caseby metis
} moreover
{ fix T11 T12 assume"T1' = Branching T11 T12" thenobtain B where"branch (B @ [True]) T1' ∧ branch (B @ [False]) T1'"using Branching by blast thenhave"branch (([True] @ B) @ [True]) (Branching T1' T2') ∧ branch (([True] @ B) @ [False]) (Branching T1' T2')"by auto thenhave ?caseby blast
} moreover
{ fix T11 T12 assume"T2' = Branching T11 T12" thenobtain B where"branch (B @ [True]) T2' ∧ branch (B @ [False]) T2'"using Branching by blast thenhave"branch (([False] @ B) @ [True]) (Branching T1' T2') ∧ branch (([False] @ B) @ [False]) (Branching T1' T2')"by auto thenhave ?caseby blast
} ultimatelyshow ?caseusing tree.exhaust by blast qed
subsection‹Internal Paths›
fun internal :: "dir list ==> tree ==> bool"where "internal [] (Branching l r) ⟷ True"
| "internal (d#ds) (Branching l r) ⟷ (if d then internal ds l else internal ds r)"
| "internal _ _ ⟷ False"
lemma internal_inv_Leaf: "¬internal b Leaf"using internal.simps by blast
lemma internal_inv_Branching_Left: "internal (Left#b) (Branching l r) ⟷ internal b l"by auto
lemma internal_inv_Branching_Right: "internal (Right#b) (Branching l r) ⟷ internal b r" by auto
lemma internal_inv_Branching: "internal p (Branching l r) ⟷ (p=[] ∨ (∃a p'. p=a#p'∧ (a ⟶ internal p' l) ∧ (¬a ⟶ internal p' r)))" (is"?L ⟷ ?R") proof assume ?L thenshow ?R by (metis internal.simps(2) neq_Nil_conv) next assume r: ?R thenshow ?L proof assume"p = []"thenshow ?L by auto next assume"∃a p'. p=a#p'∧ (a ⟶ internal p' l) ∧ (¬a ⟶ internal p' r)" thenobtain a p' where"p=a#p'∧ (a ⟶ internal p' l) ∧ (¬a ⟶ internal p' r)"by auto thenshow ?L by (cases a) auto qed qed
lemma internal_is_path: assumes"internal ds T" shows"path ds T" using assms proof (induction T arbitrary: ds) case Leaf thenhave"False"using internal_inv_Leaf by auto thenshow ?caseby auto next case (Branching T1 T2) thenobtain a b where ds_p: "ds=[] ∨ ds = a # b ∧ (a ⟶ internal b T1) ∧ (¬ a ⟶ internal b T2)"using internal_inv_Branching by blast thenhave"ds = [] ∨ (a ⟶ path b T1) ∧ (¬a ⟶ path b T2)"using Branching by auto thenshow"?case"using ds_p by (cases a) auto qed
lemma internal_prefix: assumes"internal (ds1@ds2@[d]) T" shows"internal ds1 T"(* more or less copy paste of path_prefix *) using assms proof (induction ds1 arbitrary: T) case (Cons a ds1) thenhave"∃l r. T = Branching l r"using internal_inv_Leaf by (cases T) auto thenobtain l r where p_lr: "T = Branching l r"by auto show ?case proof (cases a) assume atrue: "a" thenhave"internal ((ds1) @ ds2 @[d]) l"using p_lr Cons(2) internal_inv_Branching by auto thenhave"internal ds1 l"using Cons(1) by auto thenshow"internal (a # ds1) T"using p_lr atrue by auto next assume afalse: "~a" thenhave"internal ((ds1) @ ds2 @[d]) r"using p_lr Cons(2) internal_inv_Branching by auto thenhave"internal ds1 r"using Cons(1) by auto thenshow"internal (a # ds1) T"using p_lr afalse by auto qed next case (Nil) thenhave"∃l r. T = Branching l r"using internal_inv_Leaf by (cases T) auto thenshow ?caseby auto qed
lemma internal_branch: assumes"branch (ds1@ds2@[d]) T" shows"internal ds1 T"(* more or less copy paste of path_prefix *) using assms proof (induction ds1 arbitrary: T) case (Cons a ds1) thenhave"∃l r. T = Branching l r"using branch_inv_Leaf by (cases T) auto thenobtain l r where p_lr: "T = Branching l r"by auto show ?case proof (cases a) assume atrue: "a" thenhave"branch (ds1 @ ds2 @ [d]) l"using p_lr Cons(2) branch_inv_Branching by auto thenhave"internal ds1 l"using Cons(1) by auto thenshow"internal (a # ds1) T"using p_lr atrue by auto next assume afalse: "~a" thenhave"branch ((ds1) @ ds2 @[d]) r"using p_lr Cons(2) branch_inv_Branching by auto thenhave"internal ds1 r"using Cons(1) by auto thenshow"internal (a # ds1) T"using p_lr afalse by auto qed next case (Nil) thenhave"∃l r. T = Branching l r"using branch_inv_Leaf by (cases T) auto thenshow ?caseby auto qed
fun parent :: "dir list ==> dir list"where "parent ds = tl ds"
lemma delete_Leaf: "delete T Leaf = Leaf"by (cases T) auto
lemma path_delete: assumes"path p (delete ds T)" shows"path p T "(* What a huge proof... But the four cases can be proven shorter *) using assms proof (induction p arbitrary: T ds) case Nil thenshow ?caseby simp next case (Cons a p) thenobtain b ds' where bds'_p: "ds=b#ds'"by (cases ds) auto
have"∃dT1 dT2. delete ds T = Branching dT1 dT2"using Cons path_inv_Cons by auto thenobtain dT1 dT2 where"delete ds T = Branching dT1 dT2"by auto
thenhave"∃T1 T2. T=Branching T1 T2"(* Is there a lemma hidden here that I could extract? *) by (cases T; cases ds) auto thenobtain T1 T2 where T1T2_p: "T=Branching T1 T2"by auto
{ assume a_p: "a" assume b_p: "¬b" have"path (a # p) (delete ds T)"using Cons by - thenhave"path (a # p) (Branching (T1) (delete ds' T2))"using b_p bds'_p T1T2_p by auto thenhave"path p T1"using a_p by auto thenhave ?caseusing T1T2_p a_p by auto
} moreover
{ assume a_p: "¬a" assume b_p: "b" have"path (a # p) (delete ds T)"using Cons by - thenhave"path (a # p) (Branching (delete ds' T1) T2)"using b_p bds'_p T1T2_p by auto thenhave"path p T2"using a_p by auto thenhave ?caseusing T1T2_p a_p by auto
} moreover
{ assume a_p: "a" assume b_p: "b" have"path (a # p) (delete ds T)"using Cons by - thenhave"path (a # p) (Branching (delete ds' T1) T2)"using b_p bds'_p T1T2_p by auto thenhave"path p (delete ds' T1)"using a_p by auto thenhave"path p T1"using Cons by auto thenhave ?caseusing T1T2_p a_p by auto
} moreover
{ assume a_p: "¬a" assume b_p: "¬b" have"path (a # p) (delete ds T)"using Cons by - thenhave"path (a # p) (Branching T1 (delete ds' T2))"using b_p bds'_p T1T2_p by auto thenhave"path p (delete ds' T2)"using a_p by auto thenhave"path p T2"using Cons by auto thenhave ?caseusing T1T2_p a_p by auto
} ultimatelyshow ?caseby blast qed
lemma branch_delete: assumes"branch p (delete ds T)" shows"branch p T ∨ p=ds"(* Adapted from above *) using assms proof (induction p arbitrary: T ds) case Nil thenhave"delete ds T = Leaf"by (cases "delete ds T") auto thenhave"ds = [] ∨ T = Leaf"using delete.elims by blast thenshow ?caseby auto next case (Cons a p) thenobtain b ds' where bds'_p: "ds=b#ds'"by (cases ds) auto
have"∃dT1 dT2. delete ds T = Branching dT1 dT2"using Cons path_inv_Cons branch_is_path by blast thenobtain dT1 dT2 where"delete ds T = Branching dT1 dT2"by auto
thenhave"∃T1 T2. T=Branching T1 T2"(* Is there a lemma hidden here that I could extract? *) by (cases T; cases ds) auto thenobtain T1 T2 where T1T2_p: "T=Branching T1 T2"by auto
{ assume a_p: "a" assume b_p: "¬b" have"branch (a # p) (delete ds T)"using Cons by - thenhave"branch (a # p) (Branching (T1) (delete ds' T2))"using b_p bds'_p T1T2_p by auto thenhave"branch p T1"using a_p by auto thenhave ?caseusing T1T2_p a_p by auto
} moreover
{ assume a_p: "¬a" assume b_p: "b" have"branch (a # p) (delete ds T)"using Cons by - thenhave"branch (a # p) (Branching (delete ds' T1) T2)"using b_p bds'_p T1T2_p by auto thenhave"branch p T2"using a_p by auto thenhave ?caseusing T1T2_p a_p by auto
} moreover
{ assume a_p: "a" assume b_p: "b" have"branch (a # p) (delete ds T)"using Cons by - thenhave"branch (a # p) (Branching (delete ds' T1) T2)"using b_p bds'_p T1T2_p by auto thenhave"branch p (delete ds' T1)"using a_p by auto thenhave"branch p T1 ∨ p = ds'"using Cons by metis thenhave ?caseusing T1T2_p a_p using bds'_p a_p b_p by auto
} moreover
{ assume a_p: "¬a" assume b_p: "¬b" have"branch (a # p) (delete ds T)"using Cons by - thenhave"branch (a # p) (Branching T1 (delete ds' T2))"using b_p bds'_p T1T2_p by auto thenhave"branch p (delete ds' T2)"using a_p by auto thenhave"branch p T2 ∨ p = ds'"using Cons by metis thenhave ?caseusing T1T2_p a_p using bds'_p a_p b_p by auto
} ultimatelyshow ?caseby blast qed
lemma branch_delete_postfix: assumes"path p (delete ds T)" shows"¬(∃c cs. p = ds @ c#cs)"(* Adapted from previous proof *) using assms proof (induction p arbitrary: T ds) case Nil thenshow ?caseby simp next case (Cons a p) thenobtain b ds' where bds'_p: "ds=b#ds'"by (cases ds) auto
have"∃dT1 dT2. delete ds T = Branching dT1 dT2"using Cons path_inv_Cons by auto thenobtain dT1 dT2 where"delete ds T = Branching dT1 dT2"by auto
thenhave"∃T1 T2. T=Branching T1 T2"(* Is there a lemma hidden here that I could extract? *) by (cases T; cases ds) auto thenobtain T1 T2 where T1T2_p: "T=Branching T1 T2"by auto
{ assume a_p: "a" assume b_p: "¬b" thenhave ?caseusing T1T2_p a_p b_p bds'_p by auto
} moreover
{ assume a_p: "¬a" assume b_p: "b" thenhave ?caseusing T1T2_p a_p b_p bds'_p by auto
} moreover
{ assume a_p: "a" assume b_p: "b" have"path (a # p) (delete ds T)"using Cons by - thenhave"path (a # p) (Branching (delete ds' T1) T2)"using b_p bds'_p T1T2_p by auto thenhave"path p (delete ds' T1)"using a_p by auto thenhave"¬ (∃c cs. p = ds' @ c # cs)"using Cons by auto thenhave ?caseusing T1T2_p a_p b_p bds'_p by auto
} moreover
{ assume a_p: "¬a" assume b_p: "¬b" have"path (a # p) (delete ds T)"using Cons by - thenhave"path (a # p) (Branching T1 (delete ds' T2))"using b_p bds'_p T1T2_p by auto thenhave"path p (delete ds' T2)"using a_p by auto thenhave"¬ (∃c cs. p = ds' @ c # cs)"using Cons by auto thenhave ?caseusing T1T2_p a_p b_p bds'_p by auto
} ultimatelyshow ?caseby blast qed
lemma treezise_delete: assumes"internal p T" shows"treesize (delete p T) < treesize T" using assms proof (induction p arbitrary: T) case (Nil) thenhave"∃T1 T2. T = Branching T1 T2"by (cases T) auto thenobtain T1 T2 where T1T2_p: "T = Branching T1 T2"by auto thenshow ?caseby auto next case (Cons a p) thenhave"∃T1 T2. T = Branching T1 T2"using path_inv_Cons internal_is_path by blast thenobtain T1 T2 where T1T2_p: "T = Branching T1 T2"by auto show ?case proof (cases a) assume a_p: a from a_p have"delete (a#p) T = (Branching (delete p T1) T2)"using T1T2_p by auto moreover from a_p have"internal p T1"using T1T2_p Cons by auto thenhave"treesize (delete p T1) < treesize T1"using Cons by auto ultimately show ?thesis using T1T2_p by auto next assume a_p: "¬a" from a_p have"delete (a#p) T = (Branching T1 (delete p T2))"using T1T2_p by auto moreover from a_p have"internal p T2"using T1T2_p Cons by auto thenhave"treesize (delete p T2) < treesize T2"using Cons by auto ultimately show ?thesis using T1T2_p by auto qed qed
fun cutoff :: "(dir list ==> bool) ==> dir list ==> tree ==> tree"where "cutoff red ds (Branching T1 T2) = (if red ds then Leaf else Branching (cutoff red (ds@[Left]) T1) (cutoff red (ds@[Right]) T2))"
| "cutoff red ds Leaf = Leaf" text‹Initially you should call @{const cutoff} with @{term "ds = []"}.
If all branches are red, then @{const cutoff} gives a subtree.
If all branches are red, then so are the ones in @{const cutoff}.
The internal paths of @{const cutoff} are not red.›
lemma treesize_cutoff: "treesize (cutoff red ds T) ≤ treesize T" proof (induction T arbitrary: ds) case Leaf thenshow ?caseby auto next case (Branching T1 T2) thenhave"treesize (cutoff red (ds@[Left]) T1) + treesize (cutoff red (ds@[Right]) T2) ≤ treesize T1 + treesize T2"using add_mono by blast thenshow ?caseby auto qed
abbreviation anypath :: "tree ==> (dir list ==> bool) ==> bool"where "anypath T P ≡∀p. path p T ⟶ P p"
abbreviation anybranch :: "tree ==> (dir list ==> bool) ==> bool"where "anybranch T P ≡∀p. branch p T ⟶ P p"
abbreviation anyinternal :: "tree ==> (dir list ==> bool) ==> bool"where "anyinternal T P ≡∀p. internal p T ⟶ P p"
lemma cutoff_branch': assumes"anybranch T (λb. red(ds@b))" shows"anybranch (cutoff red ds T) (λb. red(ds@b))" using assms proof (induction T arbitrary: ds) (* This proof seems a bit excessive for such a simple theorem *) case (Leaf) let ?T = "cutoff red ds Leaf"
{ fix b assume"branch b ?T" thenhave"branch b Leaf"by auto thenhave"red(ds@b)"using Leaf by auto
} thenshow ?caseby simp next case (Branching T1 T2) let ?T = "cutoff red ds (Branching T1 T2)" from Branching have"∀p. branch (Left#p) (Branching T1 T2) ⟶ red (ds @ (Left#p))"byblast thenhave"∀p. branch p T1⟶ red (ds @ (Left#p))"by auto thenhave"anybranch T1 (λp. red ((ds @ [Left]) @ p))"by auto thenhave aa: "anybranch (cutoff red (ds @ [Left]) T1) (λp. red ((ds @ [Left]) @ p)) "using Branching by blast
from Branching have"∀p. branch (Right#p) (Branching T1 T2) ⟶ red (ds @ (Right#p))"by blast thenhave"∀p. branch p T2⟶ red (ds @ (Right#p))"by auto thenhave"anybranch T2 (λp. red ((ds @ [Right]) @ p))"by auto thenhave bb: "anybranch (cutoff red (ds @ [Right]) T2) (λp. red ((ds @ [Right]) @ p)) "using Branching by blast
{ fix b assume b_p: "branch b ?T" have"red ds ∨¬red ds"by auto thenhave"red(ds@b)" proof assume ds_p: "red ds" thenhave"?T = Leaf"by auto thenhave"b = []"using b_p branch_inv_Leaf by auto thenshow"red(ds@b)"using ds_p by auto next assume ds_p: "¬red ds" let ?T1' = "cutoff red (ds@[Left]) T1" let ?T2' = "cutoff red (ds@[Right]) T2" from ds_p have"?T = Branching ?T1' ?T2'"by auto from this b_p obtain a b' where"b = a # b' ∧ (a ⟶ branch b' ?T1') ∧ (¬a ⟶ branch b' ?T2' )"using branch_inv_Branching[of b ?T1' ?T2'] by auto thenshow"red(ds@b)"using aa bb by (cases a) auto qed
} thenshow ?caseby blast qed
lemma cutoff_branch: assumes"anybranch T (λp. red p)" shows"anybranch (cutoff red [] T) (λp. red p)" using assms cutoff_branch'[of T red "[]"] by auto
lemma cutoff_internal': assumes"anybranch T (λb. red(ds@b))" shows"anyinternal (cutoff red ds T) (λb. ¬red(ds@b))" using assms proof (induction T arbitrary: ds) (* This proof seems a bit excessive for such a simple theorem *) case (Leaf) thenshow ?caseusing internal_inv_Leaf by simp next case (Branching T1 T2) let ?T = "cutoff red ds (Branching T1 T2)" from Branching have"∀p. branch (Left#p) (Branching T1 T2) ⟶ red (ds @ (Left#p))"byblast thenhave"∀p. branch p T1⟶ red (ds @ (Left#p))"by auto thenhave"anybranch T1 (λp. red ((ds @ [Left]) @ p))"by auto thenhave aa: "anyinternal (cutoff red (ds @ [Left]) T1) (λp. ¬ red ((ds @ [Left]) @ p))"using Branching by blast
from Branching have"∀p. branch (Right#p) (Branching T1 T2) ⟶ red (ds @ (Right#p))"by blast thenhave"∀p. branch p T2⟶ red (ds @ (Right#p))"by auto thenhave"anybranch T2 (λp. red ((ds @ [Right]) @ p))"by auto thenhave bb: "anyinternal (cutoff red (ds @ [Right]) T2) (λp. ¬ red ((ds @ [Right]) @ p))"using Branching by blast
{ fix p assume b_p: "internal p ?T" thenhave ds_p: "¬red ds"using internal_inv_Leaf by auto have"p=[] ∨ p≠[]"by auto thenhave"¬red(ds@p)" proof assume"p=[]"thenshow"¬red(ds@p)"using ds_p by auto next let ?T1' = "cutoff red (ds@[Left]) T1" let ?T2' = "cutoff red (ds@[Right]) T2" assume"p≠[]" moreover have"?T = Branching ?T1' ?T2'"using ds_p by auto ultimately obtain a p' where b_p: "p = a # p' ∧ (a ⟶ internal p' (cutoff red (ds @ [Left]) T1)) ∧ (¬ a ⟶ internal p' (cutoff red (ds @ [Right]) T2))" using b_p internal_inv_Branching[of p ?T1' ?T2'] by auto thenhave"¬red(ds @ [a] @ p')"using aa bb by (cases a) auto thenshow"¬red(ds @ p)"using b_p by simp qed
} thenshow ?caseby blast qed
lemma cutoff_internal: assumes"anybranch T red" shows"anyinternal (cutoff red [] T) (λp. ¬red p)" using assms cutoff_internal'[of T red "[]"] by auto
lemma cutoff_branch_internal': assumes"anybranch T red" shows"anyinternal (cutoff red [] T) (λp. ¬red p) ∧ anybranch (cutoff red [] T) (λp. red p)" using assms cutoff_internal[of T] cutoff_branch[of T] by blast
lemma cutoff_branch_internal: assumes"anybranch T red" shows"∃T'. anyinternal T' (λp. ¬red p) ∧ anybranch T' (λp. red p)" using assms cutoff_branch_internal' by blast
section‹Possibly Infinite Trees› text‹Possibly infinite trees are of type @{typ "dir list set"}.›
abbreviation wf_tree :: "dir list set ==> bool"where "wf_tree T ≡ (∀ds d. (ds @ d) ∈ T ⟶ ds ∈ T)"
text‹The subtree in with root r› fun subtree :: "dir list set ==> dir list ==> dir list set"where "subtree T r = {ds ∈ T. ∃ds'. ds = r @ ds'}"
text‹A subtree of a tree is either in the left branch, the right branch, or is the tree itself› lemma subtree_pos: "subtree T ds ⊆ subtree T (ds @ [Left]) ∪ subtree T (ds @ [Right]) ∪ {ds}" proof (rule subsetI; rule Set.UnCI) let ?subtree = "subtree T" fix x assume asm: "x ∈ ?subtree ds" assume"x ∉ {ds}" thenhave"x ≠ ds"by simp thenhave"∃e d. x = ds @ [d] @ e"using asm list.exhaust by auto thenhave"(∃e. x = ds @ [Left] @ e) ∨ (∃e. x = ds @ [Right] @ e)"using bool.exhaust by auto thenshow"x ∈ ?subtree (ds @ [Left]) ∪ ?subtree (ds @ [Right])"using asm by auto qed
subsection‹Infinite Paths›
abbreviation wf_infpath :: "(nat ==> 'a list) ==> bool"where "wf_infpath f ≡ (f 0 = []) ∧ (∀n. ∃a. f (Suc n) = (f n) @ [a])"
lemma infpath_length: assumes"wf_infpath f" shows"length (f n) = n" using assms proof (induction n) case0thenshow ?caseby auto next case (Suc n) thenshow ?caseby (metis length_append_singleton) qed
lemma chain_prefix: assumes"wf_infpath f" assumes"n1≤ n2" shows"∃a. (f n1) @ a = (f n2)" using assms proof (induction n2) case (Suc n2) thenhave"n1≤ n2∨ n1 = Suc n2"by auto thenshow ?case proof assume"n1≤ n2" thenobtain a where a: "f n1 @ a = f n2"using Suc by auto have b: "∃b. f (Suc n2) = f n2 @ [b]"using Suc by auto from a b have"∃b. f n1 @ (a @ [b]) = f (Suc n2)"by auto thenshow"∃c. f n1 @ c = f (Suc n2)"by blast next assume"n1 = Suc n2" thenhave"f n1 @ [] = f (Suc n2)"by auto thenshow"∃a. f n1 @ a = f (Suc n2)"by auto qed qed auto
text‹If we make a lookup in a list, then looking up in an extension gives us the same value.› lemma ith_in_extension: assumes chain: "wf_infpath f" assumes smalli: "i < length (f n1)" assumes n1n2: "n1≤ n2" shows"f n1 ! i = f n2 ! i" proof - from chain n1n2have"∃a. f n1 @ a = f n2"using chain_prefix by blast thenobtain a where a_p: "f n1 @ a = f n2"by auto have"(f n1 @ a) ! i = f n1 ! i"using smalli by (simp add: nth_append) thenshow ?thesis using a_p by auto qed
section‹König's Lemma›
lemma inf_subs: assumes inf: "¬finite(subtree T ds)" shows"¬finite(subtree T (ds @ [Left])) ∨¬finite(subtree T (ds @ [Right]))" proof - let ?subtree = "subtree T"
{ assume asms: "finite(?subtree(ds @ [Left]))" "finite(?subtree(ds @ [Right]))" have"?subtree ds ⊆ ?subtree (ds @ [Left] ) ∪ ?subtree (ds @ [Right]) ∪ {ds} " using subtree_pos by auto thenhave"finite(?subtree (ds))"using asms by (simp add: finite_subset)
} thenshow"¬finite(?subtree (ds @ [Left])) ∨¬finite(?subtree (ds @ [Right]))"using inf by auto qed
fun buildchain :: "(dir list ==> dir list) ==> nat ==> dir list"where "buildchain next 0 = []"
| "buildchain next (Suc n) = next (buildchain next n)"
from wellformed have prefix: "∀ds d. (ds @ d) ∈ T ⟶ ds ∈ T"by blast
{ fix n have"(?c n) ∈ T ∧¬finite (?subtree (?c n))" proof (induction n) case0 have"∃ds. ds ∈ T"using inf by (simp add: not_finite_existsD) thenobtain ds where"ds ∈ T"by auto thenhave"([]@ds) ∈ T"by auto thenhave"[] ∈ T"using prefix by blast thenshow ?caseusing inf by auto next case (Suc n) from Suc have next_in: "(?c n) ∈ T"by auto from Suc have next_inf: "¬finite (?subtree (?c n))"by auto
from next_inf have next_next_inf: "¬finite (?subtree (?nextnode (?c n)))" using inf_subs by auto thenhave"∃ds. ds ∈ ?subtree (?nextnode (?c n))" by (simp add: not_finite_existsD) thenobtain ds where dss: "ds ∈ ?subtree (?nextnode (?c n))"by auto thenhave"ds ∈ T""∃suf. ds = (?nextnode (?c n)) @ suf"by auto thenobtain suf where"ds ∈ T ∧ ds = (?nextnode (?c n)) @ suf"by auto thenhave"(?nextnode (?c n)) ∈ T" using prefix by blast
thenhave"(?c (Suc n)) ∈ T"by auto thenshow ?caseusing next_next_inf by auto qed
} thenshow"wf_infpath ?c ∧ (∀n. (?c n)∈ T) "using is_chain by auto qed
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.