Theory Valid_List_Util
theory Valid_List_Util
imports List_Lexorder_Util List_Lexorder_NS Valid_List
begin
section ‹Order Equivalence›
lemma valid_list_list_less_equiv_list_less_ns:
assumes "valid_list s1"
and "valid_list s2"
shows "s1 < s2 = list_less_ns s1 s2"
proof
assume "s1 < s2"
hence "s1 ≠ s2"
by simp
with valid_list_neqE[OF assms(1,2)]
obtain x y as bs cs where
"s1 = as @ x # bs" "s2 = as @ y # cs" "x ≠ y"
by blast
hence "x < y"
by (metis ‹s1 < s2› linorder_less_linear list_less_ex order_less_imp_not_less)
then have "list_less_ns_ex s1 s2"
using ‹s1 = as @ x # bs› ‹s2 = as @ y # cs› list_less_ns_ex_def by fastforce
then show "list_less_ns s1 s2"
by (simp add: list_less_ns_alt_def)
next
assume "list_less_ns s1 s2"
hence "s1 ≠ s2"
by fastforce
with valid_list_neqE[OF assms(1,2)]
obtain x y as bs cs where
"s1 = as @ x # bs" "s2 = as @ y # cs" "x ≠ y"
by blast
hence "x < y"
by (metis ‹list_less_ns s1 s2› list.distinct(1) list.sel(1) list_less_ns_app_same
list_less_ns_recurse)
then show "s1 < s2"
using ‹s1 = as @ x # bs› ‹s2 = as @ y # cs› list_less_ex by fastforce
qed
lemma valid_list_list_less_eq_equiv_list_less_eq_ns:
assumes "valid_list s1"
and "valid_list s2"
shows "s1 ≤ s2 = list_less_eq_ns s1 s2"
by (simp add: assms order_le_less ordlistns.le_less valid_list_list_less_equiv_list_less_ns)
section ‹Classical Lexicographical Order›
lemma valid_list_list_less_imp:
assumes "valid_list (xs @ [bot])"
and "valid_list (ys @ [bot])"
and "(xs @ [bot]) < (ys @ [bot])"
shows "xs < ys"
proof -
from assms(3)
have "xs @ [bot] ≠ ys @ [bot]"
by fastforce
with valid_list_neqE[OF assms(1,2)]
obtain x y as bs cs where
"xs @ [bot] = as @ x # bs" "ys @ [bot] = as @ y # cs" "x ≠ y"
by blast
hence "x < y"
by (metis assms(3) linorder_less_linear list_less_ex order_less_imp_not_less)
then show ?thesis
by (metis ‹xs @ [bot] = as @ x # bs› ‹ys @ [bot] = as @ y # cs› append_self_conv
bot.extremum_strict butlast.simps(2) butlast_append last_snoc list_less_ex
list_neq_rc1)
qed
lemma strict_mono_on_list_less_map:
fixes α :: "'a :: preorder ⇒ 'b :: ord"
assumes "strict_mono_on A α"
and "set xs ⊆ A"
and "set ys ⊆ A"
and "xs < ys"
shows "(map α xs) < (map α ys)"
using assms(2-4)
proof (induct xs arbitrary: ys)
case Nil
then show ?case
using list_le_def by fastforce
next
case (Cons a xs)
note IH = this
have "∃z zs. a ≤ z ∧ ys = z # zs"
by (metis Cons_less_Cons IH(4) dual_order.refl dual_order.strict_iff_not neq_Nil_conv
not_less_Nil)
then obtain z zs where
"a ≤ z" "ys = z # zs"
by blast
then show ?case
using IH assms(1) strict_mono_onD by fastforce
qed
lemma strict_mono_list_less_map:
assumes "strict_mono α"
and "xs < ys"
shows "map α xs < map α ys"
using assms(1) assms(2) strict_mono_on_list_less_map by blast
lemma strict_mono_on_map_list_less:
fixes α :: "'a :: linorder ⇒ 'b :: order"
assumes "strict_mono_on A α"
and "set xs ⊆ A"
and "set ys ⊆ A"
and "(map α xs) < (map α ys)"
shows "xs < ys"
using assms(2-4)
proof (induct xs arbitrary: ys)
case Nil
then show ?case
using list_le_def by fastforce
next
case (Cons a xs)
note IH = this
have "ys = [] ∨ (∃b zs. ys = b # zs)"
using neq_Nil_conv by blast
moreover
have "ys = [] ⟹ ?case"
using Cons.prems by auto
moreover
have "∃b zs. ys = b # zs ⟹ ?case"
by (metis IH(2-4) assms(1) linorder_neq_iff order_less_asym strict_mono_on_list_less_map)
ultimately show ?case
by blast
qed
lemma strict_mono_map_list_less:
fixes α :: "'a :: linorder ⇒ 'b :: order"
assumes "strict_mono α"
and "(map α xs) < (map α ys)"
shows "xs < ys"
using assms(1) assms(2) strict_mono_on_map_list_less by blast
section ‹Non-standard Lexicographical Ordering›
lemma sorted_list_less_ns:
assumes "sorted (a # bs @ [c])"
and "c < d"
shows "list_less_ns (a # bs @ [c, d] @ xs) (bs @ [c, d] @ ys)"
using assms
proof (induct bs arbitrary: a)
case Nil
then show ?case
by (metis append_Cons append_Nil le_less list_less_ns_cons_diff list_less_ns_cons_same sorted2)
next
case (Cons a bs x)
note IH = this
from IH(2)
have "sorted (a # bs @ [c])"
by simp
with IH(1)[OF _ assms(2)]
have "list_less_ns (a # bs @ [c, d] @ xs) (bs @ [c, d] @ ys)" .
with sorted_nth_mono[OF IH(2), of 0 "Suc 0", simplified]
show ?case
by (simp add: list_less_ns_cons)
qed
lemma rev_sorted_list_less_ns:
assumes "sorted (rev (a # bs @ [c]))"
and "c > d"
shows "list_less_ns (bs @ [c, d] @ xs) (a # bs @ [c, d] @ ys)"
using assms
proof (induct bs arbitrary: a)
case Nil
then show ?case
using list_less_ns_cons list_less_ns_cons_diff by fastforce
next
case (Cons a bs x)
note IH = this
from IH(2)
have "sorted (rev (a # bs @ [c]))"
by (simp add: sorted_append)
with IH(1)[OF _ assms(2)]
have "list_less_ns (bs @ [c, d] @ xs) (a # bs @ [c, d] @ ys)" .
with sorted_rev_nth_mono[OF IH(2), of 0 "Suc 0", simplified]
show ?case
using list_less_ns_cons by auto
qed
lemma sorted_cons_list_less_ns:
assumes "sorted (a # bs)"
shows "list_less_ns (a # bs) bs"
using assms
proof (induct bs arbitrary: a)
case Nil
then show ?case
by (simp add: list_less_ns_nil)
next
case (Cons a bs x)
note IH = this
from IH(2)
have "sorted (a # bs)"
by simp
with IH(1)
have "list_less_ns (a # bs) bs" .
with sorted_nth_mono[OF IH(2), of 0 "Suc 0", simplified]
show ?case
by (simp add: list_less_ns_cons)
qed
end