Theory FormalSSA_Misc
section ‹Prelude›
subsection ‹Miscellaneous Lemmata›
theory FormalSSA_Misc
imports Main "HOL-Library.Sublist"
begin
lemma length_1_last_hd: "length ns = 1 ⟹ last ns = hd ns"
by (metis One_nat_def append.simps(1) append_butlast_last_id diff_Suc_Suc diff_zero length_0_conv length_butlast list.sel(1) zero_neq_one)
lemma not_in_butlast[simp]: "⟦x ∈ set ys; x ∉ set (butlast ys)⟧ ⟹ x = last ys"
apply (cases "ys = []")
apply simp
apply (subst(asm) append_butlast_last_id[symmetric])
by (simp_all del:append_butlast_last_id)
lemma in_set_butlastI: "x ∈ set xs ⟹ x ≠ last xs ⟹ x ∈ set (butlast xs)"
by (metis append_butlast_last_id append_is_Nil_conv list.distinct(1) rotate1.simps(2) set_ConsD set_rotate1 split_list)
lemma butlast_strict_prefix: "xs ≠ [] ⟹ strict_prefix (butlast xs) xs"
by (metis append_butlast_last_id strict_prefixI')
lemma set_tl: "set (tl xs) ⊆ set xs"
by (metis set_mono_suffix suffix_tl)
lemma in_set_tlD[elim]: "x ∈ set (tl xs) ⟹ x ∈ set xs"
using set_tl[of xs] by auto
lemma suffix_unsnoc:
assumes "suffix xs ys" "xs ≠ []"
obtains x where "xs = butlast xs@[x]" "ys = butlast ys@[x]"
by (metis append_butlast_last_id append_is_Nil_conv assms(1) assms(2) last_appendR suffix_def)
lemma prefix_split_first:
assumes "x ∈ set xs"
obtains as where "prefix (as@[x]) xs" and "x ∉ set as"
proof atomize_elim
from assms obtain as bs where "xs = as@x#bs ∧ x ∉ set as" by (atomize_elim, rule split_list_first)
thus "∃as. prefix (as@[x]) xs ∧ x ∉ set as" by -(rule exI[where x = as], auto)
qed
lemma in_prefix[elim]:
assumes "prefix xs ys" and "x ∈ set xs"
shows "x ∈ set ys"
using assms by (auto elim!:prefixE)
lemma strict_prefix_butlast:
assumes "prefix xs (butlast ys)" "ys ≠ []"
shows "strict_prefix xs ys"
using assms unfolding append_butlast_last_id[symmetric] by (auto simp add:less_le butlast_strict_prefix prefix_order.le_less_trans)
lemma prefix_tl_subset: "prefix xs ys ⟹ set (tl xs) ⊆ set (tl ys)"
by (metis Nil_tl prefix_bot.extremum prefix_def set_mono_prefix tl_append2)
lemma suffix_tl_subset: "suffix xs ys ⟹ set (tl xs) ⊆ set (tl ys)"
by (metis append_Nil suffix_def set_mono_suffix suffix_tl suffix_order.order_trans tl_append2)
lemma set_tl_append': "set (tl (xs @ ys)) ⊆ set (tl xs) ∪ set ys"
by (metis list.sel(2) order_refl set_append set_mono_suffix suffix_tl tl_append2)
lemma last_in_tl: "length xs > 1 ⟹ last xs ∈ set (tl xs)"
by (metis One_nat_def diff_Suc_Suc last_in_set last_tl length_tl less_numeral_extra(4) list.size(3) zero_less_diff)
lemma concat_join: "xs ≠ [] ⟹ ys ≠ [] ⟹ last xs = hd ys ⟹ butlast xs@ys = xs@tl ys"
by (induction xs, auto)
lemma fold_induct[case_names Nil Cons]: "P s ⟹ (⋀x s. x ∈ set xs ⟹ P s ⟹ P (f x s)) ⟹ P (fold f xs s)"
by (rule fold_invariant [where Q = "λx. x ∈ set xs"]) simp
lemma fold_union_elem:
assumes "x ∈ fold (∪) xss xs"
obtains ys where "x ∈ ys" "ys ∈ set xss ∪ {xs}"
using assms
by (induction rule:fold_induct) auto
lemma fold_union_elemI:
assumes "x ∈ ys" "ys ∈ set xss ∪ {xs}"
shows "x ∈ fold (∪) xss xs"
using assms
by (metis Sup_empty Sup_insert Sup_set_fold Un_insert_right UnionI ccpo_Sup_singleton fold_simps(2) list.simps(15))
lemma fold_union_elemI':
assumes "x ∈ xs ∨ (∃xs ∈ set xss. x ∈ xs)"
shows "x ∈ fold (∪) xss xs"
using assms
using fold_union_elemI by fastforce
lemma fold_union_finite[intro!]:
assumes "finite xs" "∀xs ∈ set xss. finite xs"
shows "finite (fold (∪) xss xs)"
using assms by - (rule fold_invariant, auto)
lemma in_set_zip_map:
assumes "(x,y) ∈ set (zip xs (map f ys))"
obtains y' where "(x,y') ∈ set (zip xs ys)" "f y' = y"
proof-
from assms obtain i where "x = xs ! i" "y = map f ys ! i" "i < length xs" "i < length ys" by (auto simp:set_zip)
thus thesis by - (rule that[of "ys ! i"], auto simp:set_zip)
qed
lemma dom_comp_subset: "g ` dom (f ∘ g) ⊆ dom f"
by (auto simp add:dom_def)
lemma finite_dom_comp:
assumes "finite (dom f)" "inj_on g (dom (f ∘ g))"
shows "finite (dom (f ∘ g))"
proof (rule finite_imageD)
have "g ` dom (f ∘ g) ⊆ dom f" by auto
with assms(1) show "finite (g ` dom (f ∘ g))" by - (rule finite_subset)
qed (simp add:assms(2))
lemma the1_list: "∃!x ∈ set xs. P x ⟹ (THE x. x ∈ set xs ∧ P x) = hd (filter P xs)"
proof (induction xs)
case (Cons y xs)
let ?Q = "λxs x. x ∈ set xs ∧ P x"
from Cons.prems obtain x where x: "?Q (y#xs) x" by auto
have "x = hd (filter P (y#xs))"
proof (cases "x=y")
case True
with x show ?thesis by auto
next
case False
with Cons.prems x have 1: "∃!x. x ∈ set xs ∧ P x" by auto
hence "(THE x. x ∈ set xs ∧ P x) = x" using x False by - (rule the1_equality, auto)
also from 1 have "(THE x. x ∈ set xs ∧ P x) = hd (filter P xs)" by (rule Cons.IH)
finally show ?thesis using False x Cons.prems by auto
qed
thus ?case using x by - (rule the1_equality[OF Cons.prems], auto)
qed auto
lemma set_zip_leftI:
assumes "length xs = length ys"
assumes "y ∈ set ys"
obtains x where "(x,y) ∈ set (zip xs ys)"
proof-
from assms(2) obtain i where "y = ys ! i" "i < length ys" by (metis in_set_conv_nth)
with assms(1) show thesis by - (rule that[of "xs ! i"], auto simp add:set_zip)
qed
lemma butlast_idx:
assumes "y ∈ set (butlast xs)"
obtains i where "xs ! i = y" "i < length xs - 1"
apply atomize_elim
using assms proof (induction xs arbitrary:y)
case (Cons x xs)
from Cons.prems have[simp]: "xs ≠ []" by (simp split:if_split_asm)
show ?case
proof (cases "y = x")
case True
show ?thesis by (rule exI[where x=0], simp_all add:True)
next
case False
with Cons.prems have "y ∈ set (butlast xs)" by simp
from Cons.IH[OF this] obtain i where "y = xs ! i" and "i < length xs - 1" by auto
thus ?thesis by - (rule exI[where x="Suc i"], simp)
qed
qed simp
lemma butlast_idx':
assumes "xs ! i = y" "i < length xs - 1" "length xs > 1"
shows "y ∈ set (butlast xs)"
using assms proof (induction xs arbitrary:i)
case (Cons x xs)
show ?case
proof (cases i)
case 0
with Cons.prems(1,3) show ?thesis by simp
next
case (Suc j)
with Cons.prems(1)[symmetric] Cons.prems(2,3) have "y ∈ set (butlast xs)" by - (rule Cons.IH, auto)
with Cons.prems(3) show ?thesis by simp
qed
qed simp
lemma card_eq_1_singleton:
assumes "card A = 1"
obtains x where "A = {x}"
using assms[simplified] by - (drule card_eq_SucD, auto)
lemma set_take_two:
assumes "card A ≥ 2"
obtains x y where "x ∈ A" "y ∈ A" "x ≠ y"
proof-
from assms obtain k where "card A = Suc (Suc k)"
by (auto simp: le_iff_add)
from card_eq_SucD[OF this] obtain x B where x: "A = insert x B" "x ∉ B" "card B = Suc k" by auto
from card_eq_SucD[OF this(3)] obtain y where y: "y ∈ B" by auto
from x y show ?thesis by - (rule that[of x y], auto)
qed
lemma singleton_list_hd_last: "length xs = 1 ⟹ hd xs = last xs"
by (metis One_nat_def impossible_Cons last.simps length_0_conv less_nat_zero_code list.sel(1) nat_less_le neq_Nil_conv not_less_eq_eq)
lemma distinct_hd_tl: "distinct xs ⟹ hd xs ∉ set (tl xs)"
by (metis distinct.simps(2) hd_Cons_tl in_set_member list.sel(2) member_rec(2))
lemma set_mono_strict_prefix: "strict_prefix xs ys ⟹ set xs ⊆ set (butlast ys)"
by (metis append_butlast_last_id strict_prefixE strict_prefix_simps(1) prefix_snoc set_mono_prefix)
lemma set_butlast_distinct: "distinct xs ⟹ set (butlast xs) ∩ {last xs} = {}"
by (metis append_butlast_last_id butlast.simps(1) distinct_append inf_bot_right inf_commute list.set(1) set_simps(2))
lemma disjoint_elem[elim]: "A ∩ B = {} ⟹ x ∈ A ⟹ x ∉ B" by auto
lemma prefix_butlastD[elim]: "prefix xs (butlast ys) ⟹ prefix xs ys"
using strict_prefix_butlast by fastforce
lemma butlast_prefix: "prefix xs ys ⟹ prefix (butlast xs) (butlast ys)"
by (induction xs ys rule: list_induct2'; auto)
lemma hd_in_butlast: "length xs > 1 ⟹ hd xs ∈ set (butlast xs)"
by (metis butlast.simps(2) dual_order.strict_iff_order hd_Cons_tl hd_in_set length_greater_0_conv length_tl less_le_trans list.distinct(1) list.sel(1) neq0_conv zero_less_diff)
lemma nonsimple_length_gt_1: "xs ≠ [] ⟹ hd xs ≠ last xs ⟹ length xs > 1"
by (metis length_0_conv less_one nat_neq_iff singleton_list_hd_last)
lemma set_hd_tl: "xs ≠ [] ⟹ set [hd xs] ∪ set (tl xs) = set xs"
by (metis inf_sup_aci(5) rotate1_hd_tl set_append set_rotate1)
lemma fold_update_conv:
"fold (λn m. m(n ↦ g n)) xs m x =
(if (x ∈ set xs) then Some (g x) else m x)"
by (induction xs arbitrary: m) auto
lemmas removeAll_le = length_removeAll_less_eq
lemmas removeAll_less [intro] = length_removeAll_less
lemma removeAll_induct:
assumes "⋀xs. (⋀x. x ∈ set xs ⟹ P (removeAll x xs)) ⟹ P xs"
shows "P xs"
by (induct xs rule:length_induct, rule assms) auto
lemma The_Min: "Ex1 P ⟹ The P = Min {x. P x}"
apply (rule the_equality)
apply (metis (mono_tags) Min.infinite Min_in Min_singleton all_not_in_conv finite_subset insert_iff mem_Collect_eq subsetI)
by (metis (erased, opaque_lifting) Least_Min Least_equality Set.set_insert ex_in_conv finite.emptyI finite_insert insert_iff mem_Collect_eq order_refl)
lemma The_Max: "Ex1 P ⟹ The P = Max {x. P x}"
apply (rule the_equality)
apply (metis (mono_tags) Max.infinite Max_in Max_singleton all_not_in_conv finite_subset insert_iff mem_Collect_eq subsetI)
by (metis Max_singleton Min_singleton Nitpick.Ex1_unfold The_Min the_equality)
lemma set_sorted_list_of_set_remove [simp]:
"set (sorted_list_of_set (Set.remove x A)) = Set.remove x (set (sorted_list_of_set A))"
unfolding Set.remove_def
by (cases "finite A"; simp)
lemma set_minus_one: "⟦v ≠ v'; v' ∈ set vs⟧ ⟹ set vs - {v'} ⊆ {v} ⟷ set vs = {v'} ∨ set vs = {v,v'}"
by auto
lemma set_single_hd: "set vs = {v} ⟹ hd vs = v"
by (induction vs; auto)
lemma set_double_filter_hd: "⟦ set vs = {v,v'}; v ≠ v' ⟧ ⟹ hd [v'←vs . v' ≠ v] = v'"
apply (induction vs)
apply simp
apply auto
apply (case_tac "v ∈ set vs")
prefer 2
apply (subgoal_tac "set vs = {v'}")
prefer 2
apply fastforce
apply (clarsimp simp: set_single_hd)
by fastforce
lemma map_option_the: "x = map_option f y ⟹ x ≠ None ⟹ the x = f (the y)"
by (auto simp: map_option_case split: option.split prod.splits)
end