lemma sorted_Cons_iff: "sorted(x # xs) = ((∀y ∈ set xs. x < y) ∧ sorted xs)" by(simp add: sorted_wrt_Cons)
lemma sorted_snoc_iff: "sorted(xs @ [x]) = (sorted xs ∧ (∀y ∈ set xs. y < x))" by(simp add: sorted_wrt_append) (* text‹The above two rules introduce quantifiers. It turns out that in practice this is not a problem because of the simplicity of the "isin" functions that implement @{const set}. Nevertheless it is possible to avoid the quantifiers with the help of some rewrite rules:›
lemma sorted_ConsD: "sorted (y # xs) ==> x ≤ y ==> x ∉ set xs" by (auto simp: sorted_Cons_iff)
lemma sorted_snocD: "sorted (xs @ [y]) ==> y ≤ x ==> x ∉ set xs" by (auto simp: sorted_snoc_iff)
subsection‹Inserting into an ordered list without duplicates:›
fun ins_list :: "'a::linorder ==> 'a list ==> 'a list"where "ins_list x [] = [x]" | "ins_list x (a#xs) = (if x < a then x#a#xs else if x=a then a#xs else a # ins_list x xs)"
lemma set_ins_list: "set (ins_list x xs) = set xs ∪ {x}" by(induction xs) auto
lemma sorted_ins_list: "sorted xs ==> sorted(ins_list x xs)" by(induction xs rule: induct_list012) auto
lemma ins_list_sorted: "sorted (xs @ [a]) ==> ins_list x (xs @ a # ys) = (if x < a then ins_list x xs @ (a#ys) else xs @ ins_list x (a#ys))" by(induction xs) (auto simp: sorted_lems)
text‹In principle, @{thm ins_list_sorted} suffices, but the following two corollaries speed up proofs.›
corollary ins_list_sorted1: "sorted (xs @ [a]) ==> a ≤ x ==> ins_list x (xs @ a # ys) = xs @ ins_list x (a#ys)" by(auto simp add: ins_list_sorted)
corollary ins_list_sorted2: "sorted (xs @ [a]) ==> x < a ==> ins_list x (xs @ a # ys) = ins_list x xs @ (a#ys)" by(auto simp: ins_list_sorted)
subsection‹Delete one occurrence of an element from a list:›
fun del_list :: "'a ==> 'a list ==> 'a list"where "del_list x [] = []" | "del_list x (a#xs) = (if x=a then xs else a # del_list x xs)"
lemma del_list_idem: "x ∉ set xs ==> del_list x xs = xs" by (induct xs) simp_all
lemma set_del_list: "sorted xs ==> set (del_list x xs) = set xs - {x}" by(induct xs) (auto simp: sorted_Cons_iff)
lemma sorted_del_list: "sorted xs ==> sorted(del_list x xs)" apply(induction xs rule: induct_list012) apply auto by (meson order.strict_trans sorted_Cons_iff)
lemma del_list_sorted: "sorted (xs @ a # ys) ==> del_list x (xs @ a # ys) = (if x < a then del_list x xs @ a # ys else xs @ del_list x (a # ys))" by(induction xs)
(fastforce simp: sorted_lems sorted_Cons_iff intro!: del_list_idem)+
text‹In principle, @{thm del_list_sorted} suffices, but the following corollaries speed up proofs.›
corollary del_list_sorted1: "sorted (xs @ a # ys) ==> a ≤ x ==> del_list x (xs @ a # ys) = xs @ del_list x (a # ys)" by (auto simp: del_list_sorted)
corollary del_list_sorted2: "sorted (xs @ a # ys) ==> x < a ==> del_list x (xs @ a # ys) = del_list x xs @ a # ys" by (auto simp: del_list_sorted)
corollary del_list_sorted3: "sorted (xs @ a # ys @ b # zs) ==> x < b ==> del_list x (xs @ a # ys @ b # zs) = del_list x (xs @ a # ys) @ b # zs" by (auto simp: del_list_sorted sorted_lems)
corollary del_list_sorted4: "sorted (xs @ a # ys @ b # zs @ c # us) ==> x < c ==> del_list x (xs @ a # ys @ b # zs @ c # us) = del_list x (xs @ a # ys @ b # zs) @ c # us" by (auto simp: del_list_sorted sorted_lems)
corollary del_list_sorted5: "sorted (xs @ a # ys @ b # zs @ c # us @ d # vs) ==> x < d ==> del_list x (xs @ a # ys @ b # zs @ c # us @ d # vs) = del_list x (xs @ a # ys @ b # zs @ c # us) @ d # vs" by (auto simp: del_list_sorted sorted_lems)