Theory Valid_List
theory Valid_List
imports Main "../util/List_Util"
begin
section ‹Valid List›
definition
valid_list :: "('a :: {linorder, order_bot}) list ⇒ bool"
where
"valid_list s = (length s > 0 ∧ (∀i < length s - 1. s ! i ≠ bot) ∧ last s = bot)"
lemma valid_list_ex_def:
fixes s ::"('a :: {linorder, order_bot}) list"
shows "(valid_list s) =
(∃xs. s = xs @ [bot] ∧
(∀i < length xs. xs ! i ≠ bot))"
unfolding valid_list_def
proof safe
assume
"s ≠ []"
"∀i<length s - 1. s ! i ≠ bot"
"last s = bot"
then
show "∃xs. s = xs @ [bot] ∧
(∀i<length xs. xs ! i ≠ bot)"
by (metis append_butlast_last_id length_butlast nth_butlast)
qed (simp add: nth_append)+
lemma valid_list_iff_butlast_app_last:
fixes s :: "('a :: {linorder, order_bot}) list"
shows "valid_list s ⟷
s ≠ [] ∧
(∀x ∈ set (butlast s). x ≠ bot) ∧
last s = bot"
by (metis append_butlast_last_id butlast_snoc in_set_conv_nth
valid_list_def valid_list_ex_def length_greater_0_conv)
lemma valid_list_consI:
fixes s :: "('a :: {linorder, order_bot}) list"
fixes a :: 'a
assumes "valid_list s"
and "a ≠ bot"
shows "valid_list (a # s)"
using assms
by (simp add: valid_list_iff_butlast_app_last)
lemma valid_list_consD:
fixes s :: "('a :: {linorder, order_bot}) list"
fixes a :: 'a
assumes "valid_list (a # s)"
assumes "s ≠ []"
shows "valid_list s"
using assms
by (simp add: valid_list_iff_butlast_app_last)
lemma Min_valid_list:
fixes s :: "('a :: {linorder, order_bot}) list"
assumes "valid_list s"
shows "Min (set s) = bot"
by (metis assms List.finite_set Min.in_idem last_in_set min_bot valid_list_iff_butlast_app_last)
lemma valid_list_length:
fixes s :: "('a :: {linorder, order_bot}) list"
assumes "valid_list s"
shows "length s > 0"
using assms
by (clarsimp simp: valid_list_ex_def)
lemma valid_list_length_ex:
fixes s :: "('a :: {linorder, order_bot}) list"
assumes "valid_list s"
shows "∃n. length s = Suc n"
using assms
by (clarsimp simp: valid_list_ex_def)
lemma valid_list_not_nil:
fixes s :: "('a :: {linorder, order_bot}) list"
assumes "valid_list s"
shows "s ≠ []"
using assms by (simp add: valid_list_def)
lemma valid_list_Suc_mapping:
fixes f :: "'a ⇒ nat"
fixes s :: "'a list"
shows "valid_list ((map (λx. Suc (f x)) s) @ [bot])"
proof (induct s)
case (Cons a s)
note IH = this
have "map (λx. Suc (f x)) (a # s) = (Suc (f a)) # map (λx. Suc (f x)) s"
by simp
moreover
have "Suc (f a) ≠ bot"
by (simp add: bot_nat_def)
hence "valid_list ((Suc (f a)) # (map (λx. Suc (f x)) s) @ [bot])"
by (simp add: IH valid_list_consI)
ultimately
show ?case
by simp
qed (simp add: valid_list_ex_def)
lemma valid_list_app:
assumes "valid_list (xs @ y # ys)"
shows "valid_list (y # ys)"
using assms
by (induct xs) (simp add: valid_list_consD)+
lemma not_valid_list_app:
assumes "valid_list (xs @ y # ys)"
shows "¬valid_list xs"
using assms
proof (induct xs)
case Nil
then show ?case
using valid_list_not_nil by auto
next
case (Cons a xs)
then show ?case
by (metis Groups.add_ac(2) Nil_is_append_conv One_nat_def add_diff_cancel_left' append_Cons
last_ConsL list.discI list.size(4) nth_Cons_0 valid_list_consD valid_list_def)
qed
lemma valid_list_neqE:
assumes "valid_list xs" "valid_list ys" "xs ≠ ys"
shows "∃x y as bs cs. xs = as @ x # bs ∧ ys = as @ y # cs ∧ x ≠ y"
proof -
note cases = list_neq_fc[OF assms(3)]
moreover
have "¬(∃z zs. xs = ys @ z # zs)"
using assms(1) assms(2) not_valid_list_app by blast
moreover
have "¬(∃z zs. ys = xs @ z # zs)"
using assms(1) assms(2) not_valid_list_app by blast
ultimately show ?thesis
by blast
qed
end