Theory List_Proper_Interval

theory List_Proper_Interval
imports List_Lexorder Collection_Order
(*  Title:      Containers/List_Proper_Interval.thy
    Author:     Andreas Lochbihler, ETH Zurich *)

theory List_Proper_Interval imports
  "HOL-Library.List_Lexorder"
  Collection_Order
begin

section ‹Instantiate @{class proper_interval} of for @{typ "'a list"}›

lemma Nil_less_conv_neq_Nil: "[] < xs ⟷ xs ≠ []"
by(cases xs) simp_all

lemma less_append_same_iff:
  fixes xs :: "'a :: preorder list"
  shows "xs < xs @ ys ⟷ [] < ys"
by(induct xs) simp_all

lemma less_append_same2_iff:
  fixes xs :: "'a :: preorder list"
  shows "xs @ ys < xs @ zs ⟷ ys < zs"
by(induct xs) simp_all

lemma Cons_less_iff:
  fixes x :: "'a :: preorder" shows
  "x # xs < ys ⟷ (∃y ys'. ys = y # ys' ∧ (x < y ∨ x = y ∧ xs < ys'))"
by(cases ys) auto

instantiation list :: ("{proper_interval, order}") proper_interval begin

definition proper_interval_list_aux :: "'a list ⇒ 'a list ⇒ bool"
where proper_interval_list_aux_correct:
  "proper_interval_list_aux xs ys ⟷ (∃zs. xs < zs ∧ zs < ys)"

lemma proper_interval_list_aux_simps [code]:
  "proper_interval_list_aux xs [] ⟷ False"
  "proper_interval_list_aux [] (y # ys) ⟷ ys ≠ [] ∨ proper_interval None (Some y)"
  "proper_interval_list_aux (x # xs) (y # ys) ⟷ x < y ∨ x = y ∧ proper_interval_list_aux xs ys"
apply(simp_all add: proper_interval_list_aux_correct proper_interval_simps Nil_less_conv_neq_Nil)
 apply(fastforce simp add: neq_Nil_conv)
apply(rule iffI)
 apply(fastforce simp add: Cons_less_iff intro: less_trans)
apply(erule disjE)
 apply(rule exI[where x="x # xs @ [undefined]"])
 apply(simp add: less_append_same_iff)
apply(auto 4 3 simp add: Cons_less_iff)
done

fun proper_interval_list :: "'a list option ⇒ 'a list option ⇒ bool" where
  "proper_interval_list None None ⟷ True"
| "proper_interval_list None (Some xs) ⟷ (xs ≠ [])"
| "proper_interval_list (Some xs) None ⟷ True"
| "proper_interval_list (Some xs) (Some ys) ⟷ proper_interval_list_aux xs ys"
instance
proof(intro_classes)
  fix xs ys :: "'a list"
  show "proper_interval None (Some ys) ⟷ (∃zs. zs < ys)"
    by(auto simp add: Nil_less_conv_neq_Nil intro: exI[where x="[]"])
  show "proper_interval (Some xs) None ⟷ (∃zs. xs < zs)"
    by(simp add: exI[where x="xs @ [undefined]"] less_append_same_iff)
  show "proper_interval (Some xs) (Some ys) ⟷ (∃zs. xs < zs ∧ zs < ys)"
    by(simp add: proper_interval_list_aux_correct)
qed simp
end

end