Theory Sorting

subsection ‹Sorting›

text ‹Some preliminary lemmas about sorting.›

theory Sorting
  imports Main "HOL.List" "HOL-Library.Sublist"
begin

lemma insort:
  assumes "Suc l < length s"
  assumes "s ! l < (v :: 'a :: linorder)"
  assumes "s ! (l+1) > v"
  assumes "sorted_wrt (<) s"
  shows "sorted_wrt (<) ((take (Suc l) s)@v#(drop (Suc l) s))"
proof -
  have "sorted_wrt (<) (take (Suc l) s@(drop (Suc l) s))"
    using assms(4) by simp
  moreover have
    "x. x  set (take (Suc l) s) = (i. i < (Suc l)  i < length s  s ! i = x)" 
    by (metis in_set_conv_nth length_take min_less_iff_conj nth_take)
  hence "x. x  set (take (Suc l) s)  x < v"
    using assms apply (simp) 
    using less_Suc_eq sorted_wrt_nth_less by fastforce
  moreover have
    "x. x  set (drop (Suc l) s) = (i. Suc l + i < length s  s ! (Suc l + i) = x)"
    using assms(1) by (simp add:in_set_conv_nth add.commute less_diff_conv)
  hence "x. x  set (drop (Suc l) s)  x > v"
    using assms apply (simp) 
    by (metis add.right_neutral add_diff_cancel_left' diff_Suc_Suc diff_is_0_eq'
        leI le_less_trans less_imp_le sorted_wrt_iff_nth_less)
  ultimately show ?thesis
    by (simp add:sorted_wrt_append del:append_take_drop_id)
qed

lemma sorted_wrt_irrefl_distinct:
  assumes "irreflp r"
  shows "sorted_wrt r xs  distinct xs"
  using assms by (induction xs, simp, simp, meson irreflp_def)

lemma sort_set_unique_h:
  assumes "irreflp r  transp r"
  assumes "set (x#xs) = set (y#ys)" 
  assumes "z  set xs. r x z" 
  assumes "z  set ys. r y z" 
  shows "x = y  set xs = set ys"
  by (metis assms insert_eq_iff irreflp_def list.set_intros(1)
      list.simps(15) set_ConsD transpD)

lemma sort_set_unique_rel:
  assumes "irreflp r  transp r"
  assumes "set x = set y"
  assumes "sorted_wrt r x"
  assumes "sorted_wrt r y"
  shows "x = y"
proof -
  have "length x = length y" 
    using assms by (metis sorted_wrt_irrefl_distinct distinct_card)
  then show ?thesis using assms 
    apply(induct rule:list_induct2, simp, simp)
    by (metis assms(1) list.simps(15) sort_set_unique_h) 
qed

lemma sort_set_unique:
  assumes "set x = set y"
  assumes "sorted_wrt (<) (map (f :: ('a  ('b :: linorder)))  x)"
  assumes "sorted_wrt (<) (map f y)"
  shows "x = y"
  using assms apply (simp add:sorted_wrt_map) 
  by (metis (no_types, lifting) irreflp_def less_irrefl sort_set_unique_rel 
      transpD transpI transp_on_less)

text ‹If two sequences contain the same element and strictly increasing with respect.›

lemma subseq_imp_sorted:
  assumes "subseq s t"
  assumes "sorted_wrt p t"
  shows "sorted_wrt p s"
proof -
  have "sorted_wrt p s  ¬ sorted_wrt p t"
  apply (rule list_emb.induct[where P="(=)"])
  using list_emb_set assms by fastforce+
  thus ?thesis using assms by blast
qed

text ‹If a sequence @{text t} is sorted with respect to a relation @{text p} then a subsequence will 
  be as well.›

fun to_ord where "to_ord r x y = (¬(r** y x))"

lemma trancl_idemp: "r++++ x y = r++ x y" 
  by (metis r_into_rtranclp reflclp_tranclp rtranclp_idemp rtranclp_reflclp 
      rtranclp_tranclp_tranclp tranclp.cases tranclp.r_into_trancl)

lemma top_sort:
  fixes rp
  assumes "acyclicP r"
  shows "finite s  (l. set l = s  sorted_wrt (to_ord r) l  distinct l)"
proof (induction "card s" arbitrary:s)
  case 0
  then show ?case by auto
next
  case (Suc n)
  hence "s  {}" by auto
  moreover 
  have "acyclicP (r++)" using assms
    by (simp add:acyclic_def trancl_def trancl_idemp)
  hence "acyclic ({(x,y). r++ x y}  s × s)"
    by (meson acyclic_subset inf_le1)
  hence "wf ({(x,y). r++ x y}  s × s)" using Suc 
    by (metis card.infinite finite_Int finite_SigmaI nat.distinct(1) 
        wf_iff_acyclic_if_finite)
  ultimately obtain z where 
    "z  s  (y. (y, z)   ({(x,y). r++ x y}  s × s)  y  s)" 
    by (metis ex_in_conv wf_eq_minimal)
  hence z_def: "z  s  (y. r++ y z  y  s)" by blast
  hence "card (s - {z}) = n"
    by (metis One_nat_def Suc.hyps(2) card_Diff_singleton_if card.infinite 
        diff_Suc_Suc diff_zero nat.simps(3))
  then obtain l where l_def: 
    "set l = s - {z}  sorted_wrt (to_ord r) l  distinct l" 
    by (metis Zero_not_Suc card.infinite finite_Diff Suc)
  hence "set (z#l) = s" using z_def by auto
  moreover have "y  set l. ¬(r** y z)" using z_def l_def rtranclpD by force
  ultimately show ?case 
    by (metis distinct.simps(2) insert_absorb l_def list.simps(15) 
        sorted_wrt.simps(2) to_ord.elims(3))
qed

lemma top_sort_eff:
  assumes "irreflp p++"
  assumes "sorted_wrt (to_ord p) x" 
  assumes "i < length x"
  assumes "j < length x"
  assumes "(p++ (x ! i) (x ! j))"
  shows "i < j"
  using assms apply (cases "i > j")
   apply (metis sorted_wrt_nth_less r_into_rtranclp reflclp_tranclp
          rtranclp_idemp rtranclp_reflclp to_ord.simps)
  by (metis irreflp_def nat_neq_iff)

end