Theory Type_Simple_Orders

(* Title: Examples/TTS_Foundations/Orders/Type_Simple_Orders.thy
   Author: Mihails Milehins
   Copyright 2021 (C) Mihails Milehins
*)
section‹Abstract orders on types›
theory Type_Simple_Orders
  imports
    "../Foundations/FNDS_Definite_Description"
    FNDS_Auxiliary
begin



subsection‹Background›


text‹
The results presented in this section were ported 
(with amendments and additions) from the theories text‹Orderings› 
and text‹Set_Interval› in the main library of Isabelle/HOL.
›



subsection‹Order operations›


text‹Abstract order operations.›

locale ord = 
  fixes le ls :: "['a, 'a]  bool"

locale ord_syntax = ord le ls for le ls :: "['a, 'a]  bool"
begin

notation
  le ("'(≤a')") and
  le (infix "a" 50) and
  ls ("'(<a')") and
  ls (infix "<a" 50)

abbreviation (input) ge (infix "a" 50)
  where "x a y  y a x"
abbreviation (input) gt (infix ">a" 50)
  where "x >a y  y <a x"

notation
  ge ("'(≥a')") and
  ge (infix "a" 50) and
  gt ("'(>a')") and
  gt (infix ">a" 50)

end

locale ord_dual = ord le ls for le ls :: "['a, 'a]  bool"
begin

interpretation ord_syntax .
sublocale dual: ord ge gt .

end


text‹Pairs.›

locale ord_pair = orda: ord lea lsa + ordb: ord leb lsb
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

sublocale rev: ord_pair leb lsb lea lsa .

end

locale ord_pair_syntax = ord_pair lea lsa leb lsb 
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

sublocale orda: ord_syntax lea lsa + ordb: ord_syntax leb lsb .

notation lea ('(≤a'))
  and lea (infix a 50) 
  and lsa ('(<a')) 
  and lsa (infix <a 50)
  and leb ('(≤b'))
  and leb (infix b 50) 
  and lsb ('(<b')) 
  and lsb (infix <b 50)

notation orda.ge ('(≥a')) 
  and orda.ge (infix a 50) 
  and orda.gt ('(>a')) 
  and orda.gt (infix >a 50)
  and ordb.ge ('(≥b')) 
  and ordb.ge (infix b 50) 
  and ordb.gt ('(>b')) 
  and ordb.gt (infix >b 50)

end

locale ord_pair_dual = ord_pair lea lsa leb lsb 
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

interpretation ord_pair_syntax .

sublocale ord_dual: ord_pair (≤a) (<a) (≥b) (>b) .
sublocale dual_ord: ord_pair (≥a) (>a) (≤b) (<b) .
sublocale dual_dual: ord_pair (≥a) (>a) (≥b) (>b) .

end



subsection‹Preorders›


subsubsection‹Definitions›


text‹Abstract preorders.›

locale preorder = ord le ls for le ls :: "['a, 'a]  bool" +
  assumes less_le_not_le: "ls x y  le x y  ¬ (le y x)"
    and order_refl[iff]: "le x x"
    and order_trans: "le x y  le y z  le x z"

locale preorder_dual = preorder le ls for le ls :: "['a, 'a]  bool"
begin

interpretation ord_syntax .

sublocale ord_dual .

sublocale dual: preorder ge gt 
  by standard (auto simp: less_le_not_le intro: order_trans)

end


text‹Pairs.›

locale ord_preorder = ord_pair lea lsa leb lsb + ordb: preorder leb lsb 
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"

locale ord_preorder_dual = ord_preorder lea lsa leb lsb
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

interpretation ord_pair_syntax .

sublocale ord_pair_dual .
sublocale ord_dual: ord_preorder (≤a) (<a) (≥b) (>b)
  by unfold_locales (auto simp: ordb.less_le_not_le intro: ordb.order_trans)
sublocale dual_ord: ord_preorder (≥a) (>a) (≤b) (<b) 
  by (rule ord_preorder_axioms)
sublocale dual_dual: ord_preorder (≥a) (>a) (≥b) (>b)
  by (rule ord_dual.ord_preorder_axioms)

end

locale preorder_pair = ord_preorder lea lsa leb lsb + orda: preorder lea lsa
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

sublocale rev: preorder_pair leb lsb lea lsa ..

end

locale preorder_pair_dual = preorder_pair lea lsa leb lsb
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

interpretation ord_pair_syntax .

sublocale ord_preorder_dual ..
sublocale ord_dual: preorder_pair (≤a) (<a) (≥b) (>b) ..
sublocale dual_ord: preorder_pair (≥a) (>a) (≤b) (<b) 
  by unfold_locales (auto intro: orda.order_trans simp: orda.less_le_not_le)
sublocale dual_dual: preorder_pair (≥a) (>a) (≥b) (>b) ..

end


subsubsection‹Results›

context preorder
begin

interpretation ord_syntax .


text‹Reflexivity.›

lemma eq_refl: 
  assumes "x = y"
  shows "x a y" 
  using assms by (rule ssubst) (rule order_refl)  
  
lemma less_irrefl[iff]: "¬ x <a x" by (simp add: less_le_not_le)

lemma less_imp_le: 
  assumes "x <a y"
  shows "x a y" 
  using assms by (simp add: less_le_not_le)

lemma strict_implies_not_eq: 
  assumes "a <a b"
  shows "a  b" 
  using assms by blast


text‹Asymmetry.›

lemma less_not_sym: 
  assumes "x <a y"
  shows "¬ (y <a x)"
  using assms by (simp add: less_le_not_le)

lemma asym: 
  assumes "a <a b" and "b <a a" 
  shows False
  using assms by (simp add: less_not_sym)

lemma less_asym: 
  assumes "x <a y" and "(¬ P  y <a x)" 
  shows P
  using assms by (auto dest: asym)
 

text‹Transitivity.›

lemma less_trans: 
  assumes "x <a y" and "y <a z" 
  shows "x <a z"
  using assms by (auto simp: less_le_not_le intro: order_trans)

lemma le_less_trans: 
  assumes "x a y" and "y <a z" 
  shows "x <a z"  
  using assms by (auto simp: less_le_not_le intro: order_trans)

lemma less_le_trans: 
  assumes "x <a y" and "y a z" 
  shows "x <a z"
  using assms by (auto simp: less_le_not_le intro: order_trans)

lemma less_imp_not_less: 
  assumes "x <a y"
  shows "(¬ y <a x)  True"
  using assms by (elim less_asym) simp

lemma less_imp_triv: 
  assumes "x <a y"
  shows "(y <a x  P)  True"
  using assms by (elim less_asym) simp

lemma less_asym': 
  assumes "a <a b" and "b <a a" 
  shows P 
  using assms by (rule less_asym)

end



subsection‹Partial orders›


subsubsection‹Definitions›


text‹Abstract partial orders.›

locale order = preorder le ls for le ls :: "['a, 'a]  bool" +
  assumes antisym: "le x y  le y x  x = y"

locale order_dual = order le ls for le ls :: "['a, 'a]  bool"
begin

interpretation ord_syntax .

sublocale preorder_dual ..

sublocale dual: order ge gt 
  unfolding order_def order_axioms_def
  apply unfold_locales
  apply(rule conjI)
  subgoal by (rule dual.preorder_axioms)
  subgoal by (simp add: antisym)
  done

end


text‹Pairs.›

locale ord_order = ord_preorder lea lsa leb lsb + ordb: order leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"

locale ord_order_dual = ord_order lea lsa leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

interpretation ord_pair_syntax .

sublocale ord_preorder_dual ..
sublocale ord_dual: ord_order (≤a) (<a) (≥b) (>b)
  by unfold_locales (simp add: ordb.antisym)
sublocale dual_ord: ord_order (≥a) (>a) (≤b) (<b) 
  by (rule ord_order_axioms)
sublocale dual_dual: ord_order (≥a) (>a) (≥b) (>b)
  by (rule ord_dual.ord_order_axioms)

end

locale preorder_order = ord_order lea lsa leb lsb + orda: preorder lea lsa
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool"
begin

sublocale preorder_pair ..

end

locale preorder_order_dual = preorder_order lea lsa leb lsb
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool" 
begin

interpretation ord_pair_syntax .

sublocale ord_order_dual ..
sublocale preorder_pair_dual ..
sublocale ord_dual: preorder_order (≤a) (<a) (≥b) (>b) .. 
sublocale dual_ord: preorder_order (≥a) (>a) (≤b) (<b) .. 
sublocale dual_dual: preorder_order (≥a) (>a) (≥b) (>b) ..

end

locale order_pair = preorder_order lea lsa leb lsb + orda: order lea lsa
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool" 
begin

sublocale rev: order_pair leb lsb lea lsa ..

end

locale order_pair_dual = order_pair lea lsa leb lsb
  for lea lsa :: "['a, 'a]  bool" and leb lsb :: "['b, 'b]  bool" 
begin

interpretation ord_pair_syntax .

sublocale preorder_order_dual ..
sublocale ord_dual: order_pair (≤a) (<a) (≥b) (>b) ..
sublocale dual_ord: order_pair (≥a) (>a) (≤b) (<b) 
  by unfold_locales (simp add: orda.antisym)
sublocale dual_dual: order_pair (≥a) (>a) (≥b) (>b) ..

end


subsubsection‹Results›

context order
begin

interpretation ord_syntax .


text‹Reflexivity.›

lemma less_le: "x <a y  x a y  x  y"
  by (auto simp: less_le_not_le intro: antisym)

lemma le_less: "x a y  x <a y  x = y" by (auto simp: less_le)

lemma le_imp_less_or_eq: 
  assumes "x a y"
  shows "x <a y  x = y" 
  using assms by (simp add: le_less)

lemma less_imp_not_eq: 
  assumes "x <a y"
  shows "(x = y)  False" 
  using assms by auto

lemma less_imp_not_eq2: 
  assumes "x <a y"
  shows "(y = x)  False"
  using assms by auto


text‹Transitivity.›

lemma neq_le_trans: 
  assumes "a  b" and "a a b" 
  shows "a <a b" 
  using assms by (simp add: less_le)

lemma le_neq_trans: 
  assumes "a a b" and "a  b" 
  shows "a <a b" 
  using assms by (simp add: less_le)

text‹Asymmetry.›

lemma eq_iff: "x = y  x a y  y a x" by (blast intro: antisym)

lemma antisym_conv: 
  assumes "y a x"
  shows "x a y  x = y" 
  using assms by (blast intro: antisym)


text‹Other results.›

lemma antisym_conv1: 
  assumes "¬ x <a y"
  shows "x a y  x = y"
  using assms by (simp add: le_less)

lemma antisym_conv2: 
  assumes "x a y"
  shows "¬ x <a y  x = y"
  using assms le_less by auto

lemma leD: 
  assumes "y a x"
  shows "¬ x <a y"
  using assms by (simp add: less_le_not_le)

end



subsection‹Dense orders›


text‹Abstract dense orders.›

locale dense_order = order le ls for le ls :: "['a, 'a]  bool" +
  assumes dense: "ls x y  (z. ls x z  ls z y)"

locale dense_order_dual = dense_order le ls for le ls :: "['a, 'a]  bool"
begin

interpretation ord_syntax .

sublocale order_dual ..

sublocale dual: dense_order ge gt 
  using dense by unfold_locales auto

end


text‹Pairs.›

locale ord_dense_order = ord_order lea lsa leb lsb + ordb: dense_order leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"

locale ord_dense_order_dual = ord_dense_order lea lsa leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

interpretation ord_pair_syntax .

sublocale ord_order_dual ..
sublocale ord_dual: ord_dense_order (≤a) (<a) (≥b) (>b)
  using ordb.dense by unfold_locales blast
sublocale dual_ord: ord_dense_order (≥a) (>a) (≤b) (<b) 
  by (rule ord_dense_order_axioms)
sublocale dual_dual: ord_dense_order (≥a) (>a) (≥b) (>b)
  by (rule ord_dual.ord_dense_order_axioms)

end

locale preorder_dense_order = 
  ord_dense_order lea lsa leb lsb + orda: preorder lea lsa
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

sublocale preorder_order ..

end

locale preorder_dense_order_dual = preorder_dense_order lea lsa leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

interpretation ord_pair_syntax .

sublocale ord_dense_order_dual ..
sublocale preorder_order_dual ..
sublocale ord_dual: preorder_dense_order (≤a) (<a) (≥b) (>b) ..
sublocale dual_ord: preorder_dense_order (≥a) (>a) (≤b) (<b) ..    
sublocale dual_dual: preorder_dense_order (≥a) (>a) (≥b) (>b) ..

end

locale order_dense_order = 
  preorder_dense_order lea lsa leb lsb + orda: order lea lsa
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

sublocale order_pair ..

end

locale order_dense_order_dual = order_dense_order lea lsa leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

interpretation ord_pair_syntax .

sublocale preorder_dense_order_dual ..
sublocale order_pair_dual ..
sublocale ord_dual: order_dense_order (≤a) (<a) (≥b) (>b) ..
sublocale dual_ord: order_dense_order (≥a) (>a) (≤b) (<b) ..    
sublocale dual_dual: order_dense_order (≥a) (>a) (≥b) (>b) ..

end

locale dense_order_pair = 
  order_dense_order lea lsa leb lsb + orda: dense_order lea lsa
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"

locale dense_order_pair_dual = dense_order_pair lea lsa leb lsb
  for lea lsa :: "'a  'a  bool" and leb lsb :: "'b  'b  bool"
begin

interpretation ord_pair_syntax .

sublocale order_dense_order_dual ..
sublocale ord_dual: dense_order_pair (≤a) (<a) (≥b) (>b) ..
sublocale dual_ord: dense_order_pair (≥a) (>a) (≤b) (<b) 
  using orda.dense by unfold_locales auto
sublocale dual_dual: dense_order_pair (≥a) (>a) (≥b) (>b) ..

end



subsection‹(Unique) top and bottom elements›


text‹Abstract extremum.›

locale extremum =
  fixes extremum :: 'a 

locale ord_extremum = ord le ls + extremum extremum 
  for le ls :: "'a  'a  bool" and extremum :: 'a


text‹Concrete syntax.›

locale bot = extremum bot for bot :: 'a
begin

notation bot ("")

end

locale top = extremum top for top :: 'a
begin

notation top ("")

end



subsection‹(Unique) top and bottom elements for partial orders›


subsubsection‹Definitions›


text‹Abstract partial order with extremum.›

locale order_extremum = ord_extremum le ls extremum + order le ls
  for le ls :: "'a  'a  bool"
  and extremum :: 'a  +
  assumes extremum[simp]: "le a extremum"


text‹Concrete syntax.›

locale order_bot = 
  order_dual le ls + 
  dual: order_extremum λx y. le y x λx y. ls y x bot + 
  bot bot 
  for le ls :: "'a  'a  bool" and bot :: 'a 

locale order_top = order_dual le ls + order_extremum le ls top + top top
  for le ls :: "'a  'a  bool" and top :: 'a 


subsubsection‹Results›

context order_extremum
begin

interpretation ord_syntax .

lemma extremum_uniqueI: 
  assumes "extremum a a"
  shows "a = extremum"
  using assms by (simp add: antisym)

lemma extremum_unique: "extremum a a  a = extremum"
  by (auto intro: antisym)

lemma extremum_strict[simp]: "¬ (extremum <a a)"
  by (fastforce simp: less_le_not_le)

lemma not_eq_extremum: "a  extremum  a <a extremum"
  using le_imp_less_or_eq by (auto intro: extremum)

end



subsection‹Partial orders without top or bottom elements›


text‹Abstract partial orders without top or bottom elements.›

locale no_extremum = order le ls for le ls :: "'a  'a  bool" +
  assumes gt_ex: "y. ls x y"


text‹Concrete syntax.›

locale no_top = order_dual le ls + no_extremum le ls 
  for le ls :: "'a  'a  bool"

locale no_bot = 
  order_dual le ls + 
  dual: no_extremum λx y. le y x λx y. ls y x 
  for le ls :: "'a  'a  bool"



subsection‹Least and greatest operators›

definition Least :: "['a set, ['a, 'a]  bool, 'a  bool]  'a option" 
  ((on _ with _ : «Least» _) [1000, 1000, 1000] 10) 
  where 
    "on U with op : «Least» P  (THE x on U. P x  (yU. P y  op x y))"

ctr relativization
  synthesis ctr_simps
  assumes [transfer_domain_rule, transfer_rule]: "Domainp A = (λx. x  U)"
    and [transfer_rule]: "bi_unique A" "right_total A" 
  trp (?'a A)
  in Least_def

context ord_syntax
begin

abbreviation Least where "Least  Type_Simple_Orders.Least UNIV (≤a)"
abbreviation Greatest where "Greatest  Type_Simple_Orders.Least UNIV (≥a)"

lemmas Least_def = Least_def[of UNIV (≤a)]

end

context order
begin

interpretation ord_syntax .
                  
lemma Least_equality:
  assumes "P x" and "y. P y  x a y"
  shows "Least P = Some x"
  unfolding Least_def by (rule The_on_Some_equality) (auto simp: assms antisym)

lemma LeastI2_order:
  assumes "P x" 
    and "y. P y  x a y"
    and "x. P x  y. P y  x a y  Q x"
  obtains z where "Least P = Some z" and "Q z"
  unfolding Least_def using assms by (clarsimp simp: that Least_equality)

lemma Least_ex1:
  assumes "∃!x. P x  (y. P y  x a y)"
  obtains x where "Least P = Some x" and "P x" and "P z  x a z"
  using assms unfolding Least_def by (clarsimp simp: that Least_equality)

end



subsection‹min and max›

definition min :: "[['a, 'a]  bool, 'a, 'a]  'a" where
  "min le a b = (if le a b then a else b)"

ctr parametricity
  in min_def  

context ord_syntax
begin

abbreviation min where "min  Type_Simple_Orders.min (≤a)"
abbreviation max where "max  Type_Simple_Orders.min (≥a)"

end

context ord
begin

interpretation ord_syntax .

lemma min_absorb1: "x a y  min x y = x"
  unfolding min_def by simp

end


context order
begin

interpretation ord_syntax .

lemma min_absorb2: 
  assumes "y a x"
  shows "min x y = y"
  using assms unfolding min_def by (simp add: eq_iff)

end

context order_extremum
begin

interpretation ord_syntax .

lemma max_top[simp]: "max extremum x = extremum"
  by (simp add: ord.min_absorb1)

lemma max_top2[simp]: "max x extremum = extremum"
  unfolding min_def by (simp add: extremum_uniqueI)

lemma min_top[simp]: "min extremum x = x" by (simp add: min_absorb2)

lemma min_top2[simp]: "min x extremum = x"  by (simp add: min_def top_unique)

end



subsection‹Monotonicity›

definition mono :: 
  "['a set, ['a, 'a]  bool, ['b, 'b]  bool, 'a  'b]  bool" 
  ((on _ with _ _ : «mono» _) [1000, 1000, 999, 1000] 10) 
  where
    "on Ua with op1 op2 : «mono» f  xUa. yUa. op1 x y  op2 (f x) (f y)"

ctr parametricity
  in mono_def

context ord_pair_syntax
begin

abbreviation monoab 
  where "monoab  Type_Simple_Orders.mono UNIV (≤a) (≤b)"
abbreviation monoba 
  where "monoba  Type_Simple_Orders.mono UNIV (≤b) (≤a)"
abbreviation antimonoab 
  where "antimonoab  Type_Simple_Orders.mono UNIV (≤a) (≥b)"
abbreviation antimonoba 
  where "antimonoba  Type_Simple_Orders.mono UNIV (≤b) (≥a)"
abbreviation strict_monoab 
  where "strict_monoab  Type_Simple_Orders.mono UNIV (<a) (<b)"
abbreviation strict_monoba 
  where "strict_monoba  Type_Simple_Orders.mono UNIV (<b) (<a)"
abbreviation strict_antimonoab 
  where "strict_antimonoab  Type_Simple_Orders.mono UNIV (<a) (>b)"
abbreviation strict_antimonoba 
  where "strict_antimonoba  Type_Simple_Orders.mono UNIV (<b) (>a)"

end

context ord_pair
begin

interpretation ord_pair_syntax .

lemma monoI[intro?]: 
  assumes "x y. x a y  f x b f y" 
  shows "monoab f"
  unfolding mono_def using assms by simp

lemma monoD[dest?]:
  assumes "monoab f" and "x a y" 
  shows "f x b f y"
  using assms unfolding mono_def by simp

lemma monoE:
  assumes "monoab f" and "x a y"
  obtains "f x b f y"
  using assms unfolding mono_def by simp

lemma strict_monoI[intro?]: 
  assumes "x y. x <a y  f x <b f y" 
  shows "strict_monoab f"
  unfolding mono_def using assms by simp

lemma strict_monoD[dest?]:
  assumes "strict_monoab f" and "x <a y" 
  shows "f x <b f y"
  using assms unfolding mono_def by simp

lemma strict_monoE:
  assumes "strict_monoab f" and "x <a y"
  obtains "f x <b f y"
  using assms unfolding mono_def by simp

end

context order_pair
begin

interpretation ord_pair_syntax .

lemma strict_mono_mono[dest?]: 
  assumes "strict_monoab f"
  shows "monoab f"
proof(rule monoI)
  fix x y
  assume "x a y"
  show "f x b f y"
  proof (cases "x = y")
    case True then show ?thesis by simp
  next
    case False with x a y have "x <a y" by (simp add: orda.neq_le_trans)
    with assms strict_monoD have "f x <b f y" by simp
    then show ?thesis by (simp add: ordb.le_less)
  qed
qed

end



subsection‹Set intervals›

definition ray :: "['a set, ['a, 'a]  bool, 'a]  'a set" 
  ((on _ with _ : {..⊏_}) [1000, 1000, 1000] 10) 
  where "on U with op : {..⊏u}  {x  U. op x u}" 
definition interval :: 
  "['a set, ['a, 'a]  bool, ['a, 'a]  bool, 'a, 'a]  'a set"
  ((on _ with _ _ : {_⊏..⊏_}) [1000, 1000, 999, 1000, 1000] 10) 
  where "on U with op1 op2 : {l⊏..⊏u}  
    (on U with (λx y. op1 y x) : {..⊏l})  (on U with op2 : {..⊏u})"

lemma ray_transfer[transfer_rule]:
  includes lifting_syntax
  assumes [transfer_rule]: "bi_unique A" "right_total A"
  shows "(rel_set A ===> (A ===> A ===> (=)) ===> A ===> rel_set A) ray ray"
  unfolding ray_def
proof(intro rel_funI)
  fix S :: "'a set" and S' :: "'b set" 
    and le :: "['a, 'a]  bool" and le' :: "['b, 'b]  bool" 
    and u u'
  assume [transfer_rule]: "rel_set A S S'"
    and [transfer_rule]: "(A ===> A ===> (=)) le le'"
    and [transfer_rule]: "A u u'"
  show "rel_set A {xc  S. le xc u} {x  S'. le' x u'}"
  proof(intro rel_setI)
    show "x  {xc  S. le xc u}  x'{x  S'. le' x u'}. A x x'" for x
    proof-
      assume x: "x  {xc  S. le xc u}"
      then obtain x' where [transfer_rule]: "A x x'"  
        using rel_set A S S' rel_setD1 by fastforce
      from x have "x'  {x  S'. le' x u'}" 
        apply transfer using A x x' by auto
      then show ?thesis by (auto simp: A x x')
    qed
    show "x'  {x  S'. le' x u'}  x{xc  S. le xc u}. A x x'" for x'
    proof-
      assume x': "x'  {x  S'. le' x u'}"
      then obtain x where [transfer_rule]: "A x x'"   
        using assms(2) by (auto elim: right_totalE)
      from x' have "x  {xc  S. le xc u}" by transfer auto
      then show ?thesis by (auto simp: A x x')
    qed  
  qed
qed

ctr relativization
  assumes [transfer_rule]: "right_total A" "bi_unique A"
  trp (?'a A)
  in interval_def

lemma interval_ge_le:
  "(on UNIV with (λx y. lea y x) (λx y. leb y x) : {l⊏..⊏h}) = 
    (on UNIV with leb lea : {h⊏..⊏l})"
  unfolding interval_def by auto

context ord_syntax  
begin

abbreviation lessThan ({..<a_}) 
  where "{..<au}  on UNIV with (<a) : {..⊏u}"
abbreviation atMost ({..≤a_}) 
  where "{..≤au}  on UNIV with (≤a) : {..⊏u}"
abbreviation greaterThan ({_<a..}) 
  where "{l<a..}  on UNIV with (>a) : {..⊏l}"
abbreviation atLeast ({_a..}) 
  where "{la..}  on UNIV with (≥a) : {..⊏l}"
abbreviation greaterThanLessThan ({_<a..<a_}) 
  where "{l<a..<au}  on UNIV with (<a) (<a) : {l⊏..⊏u}"
abbreviation atLeastLessThan ({_a..<a_}) 
  where "{la..<au}  on UNIV with (≤a) (<a) : {l⊏..⊏u}"
abbreviation greaterThanAtMost ({_<a..≤a_}) 
  where "{l<a..≤au}  on UNIV with (<a) (≤a) : {l⊏..⊏u}"
abbreviation atLeastAtMost ({_a..≤a_}) 
  where "{la..≤au}  on UNIV with (≤a) (≤a) : {l⊏..⊏u}"
abbreviation lessThanGreaterThan ({_>a..>a_}) 
  where "{l>a..>au}  on UNIV with (>a) (>a) : {l⊏..⊏u}"
abbreviation lessThanAtLeast ({_a..>a_}) 
  where "{la..>au}  on UNIV with (≥a) (>a) : {l⊏..⊏u}"
abbreviation atMostGreaterThan ({_>a..≥a_}) 
  where "{l>a..≥au}  on UNIV with (>a) (≥a) : {l⊏..⊏u}"
abbreviation atMostAtLeast ({_a..≥a_}) 
  where "{la..≥au}  on UNIV with (≥a) (≥a) : {l⊏..⊏u}"

end

context ord
begin

interpretation ord_syntax .

lemma lessThan_iff[iff]: "(i  {..<ak}) = (i <a k)"
  unfolding ray_def by simp

lemma atLeast_iff[iff]: "(i  {ka..}) = (k a i)"
  unfolding ray_def by simp

lemma greaterThanLessThan_iff[simp]: "(i  {l<a..<au}) = (l <a i  i <a u)"
  unfolding interval_def ray_def by simp

lemma atLeastLessThan_iff[simp]: "(i  {la..<au}) = (l a i  i <a u)"
  unfolding interval_def ray_def by simp

lemma greaterThanAtMost_iff[simp]: "(i  {l<a..≤au}) = (l <a i  i a u)"
  unfolding interval_def ray_def by simp

lemma atLeastAtMost_iff[simp]: "(i  {la..≤au}) = (l a i  i a u)"
  unfolding interval_def ray_def by simp

lemma greaterThanLessThan_eq: "{a<a..<ab} = {a<a..}  {..<ab}"
  unfolding interval_def ray_def by simp

end

context ord_pair_syntax
begin

notation orda.lessThan ({..<a_}) 
  and orda.atMost ({..≤a_}) 
  and orda.greaterThan ({_<a..}) 
  and orda.atLeast ({_a..}) 
  and orda.greaterThanLessThan ({_<a..<a_}) 
  and orda.atLeastLessThan ({_a..<a_}) 
  and orda.greaterThanAtMost ({_<a..≤a_}) 
  and orda.atLeastAtMost ({_a..≤a_}) 
  and orda.lessThanGreaterThan ({_>a..>a_})
  and orda.lessThanAtLeast ({_a..>a_}) 
  and orda.atMostGreaterThan ({_>a..≥a_}) 
  and orda.atMostAtLeast ({_a..≥a_}) 
  and ordb.lessThan ({..<b_}) 
  and ordb.atMost ({..≤b_}) 
  and ordb.greaterThan ({_<b..}) 
  and ordb.atLeast ({_b..}) 
  and ordb.greaterThanLessThan ({_<b..<b_}) 
  and ordb.atLeastLessThan ({_b..<b_}) 
  and ordb.greaterThanAtMost ({_<b..≤b_}) 
  and ordb.atLeastAtMost ({_b..≤b_})
  and ordb.lessThanGreaterThan ({_>b..>b_})
  and ordb.lessThanAtLeast ({_b..>b_}) 
  and ordb.atMostGreaterThan ({_>b..≥b_}) 
  and ordb.atMostAtLeast ({_b..≥b_})

end

context preorder
begin

interpretation ord_syntax .

lemma Ioi_le_Ico: "{a<a..}  {aa..}"
  unfolding ray_def by (fastforce simp: less_le_not_le)

end

context preorder
begin

interpretation ord_syntax .

interpretation preorder_dual le ls
  by (rule preorder_dual.intro[OF preorder_axioms])

lemma single_Diff_lessThan[simp]: "{k} - {..<ak} = {k}" by auto

lemma atLeast_subset_iff[iff]: "({xa..}  {ya..}) = (y a x)"
  by (auto intro: order_trans)

lemma atLeastatMost_empty[simp]: 
  assumes "b <a a"
  shows "{aa..≤ab} = {}"
  unfolding interval_def 
  using less_le_not_le assms
  by (metis Int_emptyI ord.lessThan_iff atLeast_iff order_trans)

lemma atLeastatMost_empty_iff[simp]: "{aa..≤ab} = {}  (¬ a a b)"
  by auto (blast intro: order_trans)

lemma atLeastatMost_empty_iff2[simp]: "{} = {aa..≤ab}  (¬ a a b)"
  by auto (blast intro: order_trans)

lemma atLeastLessThan_empty[simp]: 
  assumes "b a a" 
  shows "{aa..<ab} = {}"
  unfolding interval_def 
  using assms less_le_not_le 
  by (blast intro: order_trans)

lemma atLeastLessThan_empty_iff[simp]: "{aa..<ab} = {}  (¬ a <a b)"
  unfolding interval_def by (auto simp: le_less_trans ord.lessThan_iff)

lemma atLeastLessThan_empty_iff2[simp]: "{} = {aa..<ab}  (¬ a <a b)"
  unfolding interval_def by (auto simp: le_less_trans ord.lessThan_iff)

lemma greaterThanAtMost_empty[simp]: 
  assumes "l a k" 
  shows "{k<a..≤al} = {}" 
  using assms atLeastLessThan_empty[OF assms]
  unfolding 
    greaterThanAtMost_eq_atLeastAtMost_diff 
    atLeastLessThan_eq_atLeastAtMost_diff
  using le_less_trans by auto blast

lemma greaterThanAtMost_empty_iff[simp]: "{k<a..≤al} = {}  ¬ k <a l"
  by (auto simp: dual.le_less_trans)

lemma greaterThanAtMost_empty_iff2[simp]: "{} = {k<a..≤al}  ¬ k <a l"
  unfolding interval_def ray_def by (blast intro: less_le_trans)

lemma greaterThanLessThan_empty[simp]: 
  assumes "l a k" 
  shows "{k<a..<al} = {}"
  using assms by auto (blast intro: le_less_trans asym equals0I)

lemma atLeastatMost_subset_iff[simp]:
  "{aa..≤ab}  {ca..≤ad}  (¬ a a b)  c a a  b a d"
  by auto (blast intro: order_trans)+

lemma atLeastatMost_psubset_iff:
  "{aa..≤ab} < {ca..≤ad} 
    ((¬ a a b)  c a a  b a d  (c <a a  b <a d))  c a d"
  by (simp add: psubset_eq set_eq_iff less_le_not_le) 
    (blast intro: order_trans)

lemma Icc_subset_Ici_iff[simp]: 
  "{la..≤ah}  {l'a..} = (¬ l a h  l a l')"
  by (auto simp: subset_eq intro: order_trans)

lemma Icc_subset_Iic_iff[simp]: 
  "{la..≤ah}  {..≤ah'} = (¬ l a h  h a h')"
  unfolding interval_def ray_def by (blast intro: order_trans)+

lemma not_Ici_eq_empty[simp]: "{la..}  {}" by (auto simp: set_eq_iff)

lemmas not_empty_eq_Ici_eq_empty[simp] = not_Ici_eq_empty[symmetric]

lemma Iio_Int_singleton: "{..<ak}  {x} = (if x <a k then {x} else {})" by simp

lemma ivl_disj_int_one:
  "{..≤al}  {l<a..<au} = {}"
  "{..<al}  {la..<au} = {}"
  "{..≤al}  {l<a..≤au} = {}"
  "{..<al}  {la..≤au} = {}"
  "{l<a..≤au}  {u<a..} = {}"
  "{l<a..<au}  {ua..} = {}"
  "{la..≤au}  {u<a..} = {}"
  "{la..<au}  {ua..} = {}"
  using lessThan_iff dual.lessThan_iff by (auto simp: less_le_not_le)

lemma ivl_disj_int_two:
  "{l<a..<am}  {ma..<au} = {}"
  "{l<a..≤am}  {m<a..<au} = {}"
  "{la..<am}  {ma..<au} = {}"
  "{la..≤am}  {m<a..<au} = {}"
  "{l<a..<am}  {ma..≤au} = {}"
  "{l<a..≤am}  {m<a..≤au} = {}"
  "{la..<am}  {ma..≤au} = {}"
  "{la..≤am}  {m<a..≤au} = {}"
  using lessThan_iff by (auto simp: less_le_not_le)

end

context order
begin     

interpretation ord_syntax .

interpretation order_dual le ls
  by (rule order_dual.intro[OF order_axioms])

lemma atMost_Int_atLeast: "{..≤an}  {na..} = {n}"
  unfolding ray_def by (auto simp: eq_iff)

lemma atLeast_eq_iff[iff]: "({xa..} = {ya..}) = (x = y)" 
  unfolding ray_def using antisym by auto

lemma atLeastLessThan_eq_atLeastAtMost_diff: "{aa..<ab} = {aa..≤ab} - {b}"
  unfolding interval_def ray_def by (auto simp: less_imp_le le_less)

lemma greaterThanAtMost_eq_atLeastAtMost_diff: "{a<a..≤ab} = {aa..≤ab} - {a}"
  unfolding interval_def ray_def by (auto simp: less_imp_le le_less)

lemma atLeastAtMost_singleton[simp]: "{aa..≤aa} = {a}"
  using atMost_Int_atLeast by (fastforce simp: ray_def) 

lemma atLeastAtMost_singleton': 
  assumes "a = b"
  shows "{aa..≤ab} = {a}" 
  using assms by simp

lemma Icc_eq_Icc[simp]:
  "{la..≤ah} = {l'a..≤ah'} = (l = l'  h = h'  ¬ l a h  ¬ l' a h')"
  apply(rule iffI)
  subgoal by (metis antisym atLeastatMost_subset_iff eq_refl)
  subgoal using atLeastatMost_empty_iff by blast
  done

lemma atLeastAtMost_singleton_iff[simp]: "{aa..≤ab} = {c}  a = b  b = c"
proof
  assume "{aa..≤ab} = {c}"
  hence *: "¬ (¬ a a b)" unfolding atLeastatMost_empty_iff[symmetric] by simp
  with {aa..≤ab} = {c} have "c a a  b a c" by auto
  with * show "a = b  b = c" by (auto intro: antisym order_trans) 
qed simp

end

context order_extremum
begin

interpretation ord_syntax .

lemma atMost_eq_UNIV_iff: "{..≤ax} = UNIV  x = extremum"
  by (metis ord.lessThan_iff eq_iff UNIV_I UNIV_eq_I extremum)

end

context no_extremum
begin

interpretation ord_syntax .

interpretation order_dual le ls
  by (rule order_dual.intro[OF order_axioms])

lemma not_UNIV_le_Icc[simp]: "¬ UNIV  {la..≤ah}"
  using gt_ex[of h] by (auto simp: subset_eq less_le_not_le)

lemma not_UNIV_le_Iic[simp]: "¬ UNIV  {..≤ah}"
  using gt_ex[of h] by (auto simp: less_le_not_le)

lemma not_Ici_le_Icc[simp]: "¬ {la..}  {l'a..≤ah'}"
  using gt_ex[of h']
  by (auto simp: subset_eq less_le) 
    (blast dest: antisym_conv intro: order_trans)

lemma not_Ici_le_Iic[simp]: "¬ {la..}  {..≤ah'}"
proof
  assume "{la..}  {..≤ah'}"
  then have x: "l a x  x a h'" for x by auto
  from gt_ex obtain x where "h' <a x" by auto
  show False
  proof(cases l a x)
    case True show ?thesis 
      using x[OF True] less_le_not_le by (force simp: h' <a x)
  next
    case False
    obtain y where "x a y" and "y <a l"
      using h' <a x dual.less_le_trans by (blast intro: x less_imp_le)
    then have "x <a l" by (rule le_less_trans)
    then show ?thesis 
      using h' <a x less_le_not_le by (blast intro: x dual.less_trans)
  qed
qed

lemma not_UNIV_eq_Icc[simp]: "UNIV  {l'a..≤ah'}"
  using gt_ex by (auto simp: set_eq_iff less_le_not_le)
  
lemmas not_Icc_eq_UNIV[simp] = not_UNIV_eq_Icc[symmetric]

lemma not_UNIV_eq_Iic[simp]: "UNIV  {..≤ah'}"
  using gt_ex[of h'] not_UNIV_le_Iic by blast

lemmas not_Iic_eq_UNIV[simp] = not_UNIV_eq_Iic[symmetric]

lemma not_Icc_eq_Ici[simp]: "{la..≤ah}  {l'a..}"
  using not_Ici_le_Icc by blast

lemmas not_Ici_eq_Icc[simp] = not_Icc_eq_Ici[symmetric]

lemma not_Iic_eq_Ici[simp]: "{..≤ah}  {l'a..}"
  using not_Ici_le_Iic[of l' h] by blast

lemmas not_Ici_eq_Iic[simp] = not_Iic_eq_Ici[symmetric]

lemma greaterThan_non_empty[simp]: "{x<a..}  {}"
  using gt_ex[of x] unfolding ray_def by simp

end

context order
begin

interpretation ord_syntax .
interpretation order_pair le ls le ls ..
interpretation ord_pair_syntax le ls le ls .

lemma mono_image_least:
  assumes f_mono: "monoab f" 
    and f_img: "f ` {ma..<an} = {m'a..<an'}" 
    and "m <a n"
  shows "f m = m'"
proof -
  from f_img have "{m'a..<an'}  {}" by (force simp: assms(3))
  with f_img have "m'  f ` {ma..<an}" by auto
  then obtain k where "f k = m'" "m a k" by auto
  moreover have "m' a f m" 
    unfolding interval_def using f_img by (auto simp: assms(3))
  ultimately show "f m = m'"
    using f_mono by (auto dest: monoD intro: antisym)
qed

end



subsection‹Bounded sets›

definition bdd :: "['a set, ['a, 'a]  bool, 'a set]  bool"
  ((on _ with _ : «bdd» _) [1000, 1000, 1000] 10) 
  where "bdd U op A  (MU. x  A. op x M)"

ctr parametricity
  in bdd_def

context ord_syntax  
begin

abbreviation bdd_above where "bdd_above  bdd UNIV (≤a)"
abbreviation bdd_below where "bdd_below  bdd UNIV (≥a)"

end

context preorder
begin

interpretation ord_syntax .

interpretation preorder_dual ..

lemma bdd_aboveI[intro]: 
  assumes "x. x  A  x a M"
  shows "bdd_above A"
  using assms unfolding bdd_def by auto

lemma bdd_belowI[intro]: 
  assumes "x. x  A  m a x"
  shows "bdd_below A"
  using assms unfolding bdd_def by auto

lemma bdd_aboveI2: 
  assumes "x. x  A  f x a M"
  shows "bdd_above (f ` A)" 
  using assms by force

lemma bdd_belowI2: 
  assumes "x. x  A  m a f x"
  shows "bdd_below (f ` A)" 
  using assms by force

lemma bdd_above_empty[simp, intro]: "bdd_above {}"
  unfolding bdd_above_def by auto

lemma bdd_below_empty[simp, intro]: "bdd_below {}"
  unfolding bdd_below_def by auto

lemma bdd_above_mono: 
  assumes "bdd_above B" and "A  B" 
  shows "bdd_above A"
  using assms unfolding bdd_def by auto

lemma bdd_below_mono: 
  assumes "bdd_below B" and "A  B"
  shows "bdd_below A"
  using assms unfolding bdd_def by auto

lemma bdd_above_Int1[simp]: 
  assumes "bdd_above A"
  shows "bdd_above (A  B)"
  using assms by (auto simp: bdd_above_mono)

lemma bdd_above_Int2[simp]: 
  assumes "bdd_above B"
  shows "bdd_above (A  B)"
  using assms by (auto simp: bdd_above_mono)

lemma bdd_below_Int1[simp]: 
  assumes "bdd_below A"
  shows "bdd_below (A  B)"
  using assms by (auto simp: bdd_below_mono)

lemma bdd_below_Int2[simp]: 
  assumes "bdd_below B"
  shows "bdd_below (A  B)"
  using assms by (auto simp: bdd_below_mono)

lemma bdd_above_Ioo[simp, intro]: "bdd_above {a<a..<ab}" 
  by (auto intro!: less_imp_le)

lemma bdd_above_Ico[simp, intro]: "bdd_above {aa..<ab}" 
  by (auto intro!: less_imp_le)

lemma bdd_above_Iio[simp, intro]: "bdd_above {..<ab}"
  by (auto intro: less_imp_le)

lemma bdd_above_Ioc[simp, intro]: "bdd_above {a<a..≤ab}" by auto

lemma bdd_above_Icc[simp, intro]: "bdd_above {aa..≤ab}"
  by (auto intro: less_imp_le)

lemma bdd_above_Iic[simp, intro]: "bdd_above {..≤ab}"
  by (auto intro: less_imp_le)

lemma bdd_below_Ioo[simp, intro]: "bdd_below {a<a..<ab}"
  by (auto intro!: less_imp_le)

lemma bdd_below_Ioc[simp, intro]: "bdd_below {a<a..≤ab}"
  by (auto intro!: less_imp_le)

lemma bdd_below_Ioi[simp, intro]: "bdd_below {a<a..}"
  by (auto intro: less_imp_le)

lemma bdd_below_Ico[simp, intro]: "bdd_below {aa..<ab}" by auto

lemma bdd_below_Icc[simp, intro]: "bdd_below {aa..≤ab}" by auto

lemma bdd_below_Ici[simp, intro]: "bdd_below {aa..}"
  by (auto intro: less_imp_le)

end

context order_pair
begin

interpretation ord_pair_syntax .

lemma bdd_above_image_mono: 
  assumes "monoab f" and "orda.bdd_above A"
  shows "ordb.bdd_above (f ` A)"
  using assms by (auto simp: bdd_def mono_def)

lemma bdd_below_image_mono: 
  assumes "monoab f" and "orda.bdd_below A" 
  shows "ordb.bdd_below (f ` A)"
  using assms by (auto simp: bdd_def mono_def)

lemma bdd_above_image_antimono:
  assumes "antimonoab f" and "orda.bdd_below A" 
  shows "ordb.bdd_above (f ` A)"
  using assms by (auto simp: bdd_def mono_def)

lemma bdd_below_image_antimono: 
  assumes "antimonoab f" and "orda.bdd_above A"   
  shows "ordb.bdd_below (f ` A)"
  using assms by (auto simp: bdd_def mono_def)

end

context order_extremum
begin

interpretation ord_syntax .
interpretation order_dual ..

lemma bdd_above_top[simp, intro!]: "bdd_above A"
  by (rule bdd_aboveI[of _ extremum]) simp

end

text‹\newpage›

end