Theory Lexord_List
theory Lexord_List
imports Main
begin
typedef 'a lexlist = "{xs::'a list. True}"
morphisms unlex Lex
by auto
definition "lexlist ≡ Lex"
lemma lexlist_ext:
"Lex xs = Lex ys ⟹ xs = ys"
by (auto simp: Lex_inject)
lemma Lex_unlex [simp, code abstype]:
"Lex (unlex lxs) = lxs"
by (fact unlex_inverse)
lemma unlex_lexlist [simp, code abstract]:
"unlex (lexlist xs) = xs"
by (metis lexlist_ext unlex_inverse lexlist_def)
definition list_less :: "'a :: ord list ⇒ 'a list ⇒ bool" where
"list_less xs ys ⟷ (xs, ys) ∈ lexord {(u, v). u < v}"
definition list_le where
"list_le xs ys ⟷ list_less xs ys ∨ xs = ys"
lemma not_less_Nil [simp]: "¬ list_less x []"
by (simp add: list_less_def)
lemma Nil_less_Cons [simp]: "list_less [] (a # x)"
by (simp add: list_less_def)
lemma Cons_less_Cons [simp]: "list_less (a # x) (b # y) ⟷ a < b ∨ a = b ∧ list_less x y"
by (simp add: list_less_def)
lemma le_Nil [simp]: "list_le x [] ⟷ x = []"
unfolding list_le_def by (cases x) auto
lemma Nil_le_Cons [simp]: "list_le [] x"
unfolding list_le_def by (cases x) auto
lemma Cons_le_Cons [simp]: "list_le (a # x) (b # y) ⟷ a < b ∨ a = b ∧ list_le x y"
unfolding list_le_def by auto
lemma less_list_code [code]:
"list_less xs [] ⟷ False"
"list_less [] (x # xs) ⟷ True"
"list_less (x # xs) (y # ys) ⟷ x < y ∨ x = y ∧ list_less xs ys"
by simp_all
lemma less_eq_list_code [code]:
"list_le (x # xs) [] ⟷ False"
"list_le [] xs ⟷ True"
"list_le (x # xs) (y # ys) ⟷ x < y ∨ x = y ∧ list_le xs ys"
by simp_all
instantiation lexlist :: (ord) ord
begin
definition
lexlist_less_def: "xs < ys ⟷ list_less (unlex xs) (unlex ys)"
definition
lexlist_le_def: "(xs :: _ lexlist) ≤ ys ⟷ list_le (unlex xs) (unlex ys)"
instance ..
lemmas lexlist_ord_defs = lexlist_le_def lexlist_less_def list_le_def list_less_def
end
instance lexlist :: (order) order
proof
fix xs :: "'a lexlist"
show "xs ≤ xs" by (simp add: lexlist_le_def list_le_def)
next
fix xs ys zs :: "'a lexlist"
assume "xs ≤ ys" and "ys ≤ zs"
then show "xs ≤ zs"
apply (auto simp add: lexlist_ord_defs)
apply (rule lexord_trans)
apply (auto intro: transI)
done
next
fix xs ys :: "'a lexlist"
assume "xs ≤ ys" and "ys ≤ xs"
then show "xs = ys"
apply (auto simp add: lexlist_ord_defs)
apply (rule lexord_irreflexive [THEN notE])
defer
apply (rule lexord_trans)
apply (auto intro: transI simp: unlex_inject)
done
next
fix xs ys :: "'a lexlist"
show "xs < ys ⟷ xs ≤ ys ∧ ¬ ys ≤ xs"
apply (auto simp add: lexlist_ord_defs)
defer
apply (rule lexord_irreflexive [THEN notE])
apply auto
apply (rule lexord_irreflexive [THEN notE])
defer
apply (rule lexord_trans)
apply (auto intro: transI)
done
qed
instance lexlist :: (linorder) linorder
proof
fix xs ys :: "'a lexlist"
have "(unlex xs, unlex ys) ∈ lexord {(u, v). u < v} ∨ unlex xs = unlex ys ∨ (unlex ys, unlex xs) ∈ lexord {(u, v). u < v}"
by (rule lexord_linear) auto
then show "xs ≤ ys ∨ ys ≤ xs"
by (auto simp add: lexlist_ord_defs unlex_inject)
qed
end