Theory Functions_Monotone

✐‹creator "Kevin Kappelmann"›
subsubsection ‹Monotonicity›
theory Functions_Monotone
  imports
    Binary_Relations_Order_Base
    Function_Relators
    Predicate_Functions
    Predicates_Order
begin

paragraph ‹Summary›
text ‹Introduces the concept of monotone functions. A function is monotone
if it is related to itself - see termDep_Fun_Rel_rel.›

declare le_funI[intro]
declare le_funE[elim]

consts dep_mono_wrt :: "'a  'b  'c"
consts mono_wrt :: "'a  'b  'c"

open_bundle dep_mono_wrt_syntax
begin
notation "mono_wrt" (infixr  50)
syntax
  "_dep_mono_wrt_rel" :: "idt  idt  'a  'b  'c"
    ('(_/ _/ / _')  (_) [51, 51, 50, 50] 50)
  "_dep_mono_wrt_rel_if" :: "idt  idt  'a  bool  'b  'c"
    ('(_/ _/ / _/ |/ _')  (_) [51, 51, 50, 50, 50] 50)
  "_dep_mono_wrt_pred" :: "idt  'a  'b  'c" ('(_/ :/ _')  (_) [51, 50, 50] 50)
  "_dep_mono_wrt_pred_if" :: "idt  'a  bool  'b  'c"
    ('(_/ :/ _/ |/ _')  (_) [51, 50, 50, 50] 50)
end
syntax_consts
  "_dep_mono_wrt_rel" "_dep_mono_wrt_rel_if" "_dep_mono_wrt_pred" "_dep_mono_wrt_pred_if"  dep_mono_wrt
translations
  "(x y  R)  S"  "CONST dep_mono_wrt R (λx y. S)"
  "(x y  R | B)  S"  "CONST dep_mono_wrt R (λx y. CONST rel_if B S)"
  "(x : P)  Q"  "CONST dep_mono_wrt P (λx. Q)"
  "(x : P | B)  Q"  "CONST dep_mono_wrt P (λx. CONST pred_if B Q)"

definition "dep_mono_wrt_rel (R :: 'a  'a  bool)
  (S :: 'a  'a  'b  'b  bool) (f :: 'a  'b)  ((x y  R)  S x y) f f"
adhoc_overloading dep_mono_wrt dep_mono_wrt_rel

definition "mono_wrt_rel (R :: 'a  'a  bool) (S :: 'b  'b  bool) 
  ((_ _  R)  S) :: ('a  'b)  bool"
adhoc_overloading mono_wrt mono_wrt_rel

definition "dep_mono_wrt_pred (P :: 'a  bool) (Q :: 'a  'b  bool) (f :: 'a  'b) 
  ((x : P)  (λ(_ :: 'b). Q x)) f f"
adhoc_overloading dep_mono_wrt dep_mono_wrt_pred

definition "mono_wrt_pred (P :: 'a  bool) (Q :: 'b  bool) 
  (((_ :: 'a) : P)  Q) :: ('a  'b)  bool"
adhoc_overloading mono_wrt mono_wrt_pred

lemma mono_wrt_rel_eq_dep_mono_wrt_rel:
  "((R :: 'a  'a  bool)  (S :: 'b  'b  bool)) = ((_ _  R)  S)"
  unfolding mono_wrt_rel_def by simp

lemma mono_wrt_rel_eq_dep_mono_wrt_rel_uhint [uhint]:
  assumes "R  R'"
  and "S'  (λ(_ :: 'a) (_ :: 'a). S)"
  shows "((R :: 'a  'a  bool)  (S :: 'b  'b  bool)) = ((x y  R')  S' x y)"
  using assms by (simp add: mono_wrt_rel_eq_dep_mono_wrt_rel)

lemma mono_wrt_rel_iff_dep_mono_wrt_rel:
  "((R :: 'a  'a  bool)  (S :: 'b  'b  bool)) f 
    dep_mono_wrt R (λ(_ :: 'a) (_ :: 'a). S) (f :: 'a  'b)"
  by (simp add: mono_wrt_rel_eq_dep_mono_wrt_rel)

lemma mono_wrt_pred_eq_dep_mono_wrt_pred:
  "((P :: 'a  bool)  (Q :: 'b  bool)) = (((_ :: 'a) : P)  Q)"
  unfolding mono_wrt_pred_def by simp

lemma mono_wrt_pred_eq_dep_mono_wrt_pred_uhint [uhint]:
  assumes "P  P'"
  and "x. Q  Q' x"
  shows "((P :: 'a  bool)  (Q :: 'b  bool)) = (((x : P')  Q' x) :: ('a  'b)  bool)"
  using assms by (simp add: mono_wrt_pred_eq_dep_mono_wrt_pred)

lemma mono_wrt_pred_iff_dep_mono_wrt_pred:
  "((P :: 'a  bool)  (Q :: 'b  bool)) f  (((_ :: 'a) : P)  Q) (f :: 'a  'b)"
  by (simp add: mono_wrt_pred_eq_dep_mono_wrt_pred)

lemma dep_mono_wrt_relI [intro]:
  assumes "x y. R x y  S x y (f x) (f y)"
  shows "((x y  R)  S x y) f"
  using assms unfolding dep_mono_wrt_rel_def by blast

lemma dep_mono_wrt_relE:
  assumes "((x y  R)  S x y) f"
  obtains "x y. R x y  S x y (f x) (f y)"
  using assms unfolding dep_mono_wrt_rel_def by blast

lemma dep_mono_wrt_relD [dest]:
  assumes "((x y  R)  S x y) f"
  and "R x y"
  shows "S x y (f x) (f y)"
  using assms unfolding dep_mono_wrt_rel_def by blast

lemma dep_mono_wrt_rel_cong [cong]:
  assumes "R = R'"
  and "x y. R' x y  S x y = S' x y"
  shows "((x y  R)  S x y) = ((x y  R')  S' x y)"
  using assms by force

lemma mono_wrt_relI [intro]:
  assumes "x y. R x y  S (f x) (f y)"
  shows "(R  S) f"
  using assms by (urule dep_mono_wrt_relI)

lemma mono_wrt_relE:
  assumes "(R  S) f"
  obtains "x y. R x y  S (f x) (f y)"
  using assms by (urule (e) dep_mono_wrt_relE)

lemma mono_wrt_relD [dest]:
  assumes "(R  S) f"
  and "R x y"
  shows "S (f x) (f y)"
  using assms by (urule dep_mono_wrt_relD)

lemma dep_mono_wrt_predI [intro]:
  assumes "x. P x  Q x (f x)"
  shows "((x : P)  Q x) f"
  using assms unfolding dep_mono_wrt_pred_def by blast

lemma dep_mono_wrt_predE:
  assumes "((x : P)  Q x) f"
  obtains "x. P x  Q x (f x)"
  using assms unfolding dep_mono_wrt_pred_def by blast

lemma dep_mono_wrt_predD [dest]:
  assumes "((x : P)  Q x) f"
  and "P x"
  shows "Q x (f x)"
  using assms unfolding dep_mono_wrt_pred_def by blast

lemma dep_mono_wrt_pred_cong [cong]:
  assumes "P = P'"
  and "x. P' x  Q x = Q' x"
  shows "((x : P)  Q x) = ((x : P')  Q' x)"
  using assms by force

lemma dep_mono_wrt_pred_codom_iff_cong:
  assumes "P = P'"
  and "x. P' x  Q x (f x)  Q' x (f' x)"
  shows "((x : P)  Q x) f  ((x : P')  Q' x) f'"
  using assms by force

lemma mono_wrt_predI [intro]:
  assumes "x. P x  Q (f x)"
  shows "(P  Q) f"
  using assms by (urule dep_mono_wrt_predI)

lemma mono_wrt_predE:
  assumes "(P  Q) f"
  obtains "x. P x  Q (f x)"
  using assms by (urule (e) dep_mono_wrt_predE)

lemma mono_wrt_predD [dest]:
  assumes "(P  Q) f"
  and "P x"
  shows "Q (f x)"
  using assms by (urule dep_mono_wrt_predD)

context
  fixes R :: "'a  'a  bool" and S :: "'a  'a  'b  'b  bool" and f :: "'a  'b"
  and P :: "'a  bool" and Q :: "'a  'b  bool"
begin

lemma dep_mono_wrt_rel_if_Dep_Fun_Rel_rel_self:
  assumes "((x y  R)  S x y) f f"
  shows "((x y  R)  S x y) f"
  using assms by blast

lemma dep_mono_wrt_pred_if_Dep_Fun_Rel_pred_self:
  assumes "((x : P)  (λ_. Q x)) f f"
  shows "((x : P)  Q x) f"
  using assms by blast

lemma Dep_Fun_Rel_rel_self_if_dep_mono_wrt_rel:
  assumes "((x y  R)  S x y) f"
  shows "((x y  R)  S x y) f f"
  using assms by blast

lemma Dep_Fun_Rel_pred_self_if_dep_mono_wrt_pred:
  assumes "((x : P)  Q x) f"
  shows "((x : P)  (λ_. Q x)) f f"
  using assms by blast

corollary Dep_Fun_Rel_rel_self_iff_dep_mono_wrt_rel:
  "((x y  R)  S x y) f f  ((x y  R)  S x y) f"
  using dep_mono_wrt_rel_if_Dep_Fun_Rel_rel_self
    Dep_Fun_Rel_rel_self_if_dep_mono_wrt_rel by blast

corollary Dep_Fun_Rel_pred_self_iff_dep_mono_wrt_pred:
  "((x : P)  (λ(_ :: 'b). Q x)) f f  ((x : P)  Q x) f"
  using dep_mono_wrt_pred_if_Dep_Fun_Rel_pred_self
    Dep_Fun_Rel_pred_self_if_dep_mono_wrt_pred by blast

lemma dep_mono_wrt_rel_inv_eq [simp]:
  "((y x  R¯)  (S x y)¯) = ((x y  R)  S x y)"
  by (intro ext) force

lemma in_dom_if_rel_if_dep_mono_wrt_rel:
  assumes "((x y  R)  S x y) f"
  and "R x y"
  shows "in_dom (S x y) (f x)"
  using assms by (intro in_domI) blast

end

context
  fixes R :: "'a  'a  bool" and f :: "'a  'b"
begin

corollary in_dom_if_in_dom_if_mono_wrt_rel:
  assumes "(R  S) f"
  shows "(in_dom R  in_dom S) f"
  using assms in_dom_if_rel_if_dep_mono_wrt_rel by fast

lemma in_codom_if_rel_if_dep_mono_wrt_rel:
  assumes "((x y  R)  S x y) f"
  and "R x y"
  shows "in_codom (S x y) (f y)"
  using assms by (intro in_codomI) blast

corollary in_codom_if_in_codom_if_mono_wrt_rel:
  assumes "(R  S) f"
  shows "(in_codom R  in_codom S) f"
  using assms in_dom_if_rel_if_dep_mono_wrt_rel
  by fast

corollary in_field_if_in_field_if_mono_wrt_rel:
  assumes "(R  S) f"
  shows "(in_field R  in_field S) f"
  using assms by fast

lemma le_rel_map_if_mono_wrt_rel:
  assumes "(R  S) f"
  shows "R  rel_map f S"
  using assms by (intro le_relI) auto

lemma le_pred_map_if_mono_wrt_pred:
  assumes "(P  Q) f"
  shows "P  pred_map f Q"
  using assms by (intro le_predI) auto

lemma mono_wrt_rel_if_le_rel_map:
  assumes "R  rel_map f S"
  shows "(R  S) f"
  using assms by (intro mono_wrt_relI) auto

lemma mono_wrt_pred_if_le_pred_map:
  assumes "P  pred_map f Q"
  shows "(P  Q) f"
  using assms by (intro mono_wrt_predI) auto

corollary mono_wrt_rel_iff_le_rel_map: "(R  S) f  R  rel_map f S"
  using mono_wrt_rel_if_le_rel_map le_rel_map_if_mono_wrt_rel by auto

corollary mono_wrt_pred_iff_le_pred_map: "(P  Q) f  P  pred_map f Q"
  using mono_wrt_pred_if_le_pred_map le_pred_map_if_mono_wrt_pred by auto

end

lemma dep_mono_comp_iff_dep_mono_if_all_app_eq:
  assumes "x. A x  f (m x) = g x"
  shows "((x : (A :: _  bool))  B x) (f  m)  ((x : A)  B x) g"
  using assms by fastforce

lemma dep_mono_pred_map_comp_iff_dep_mono_if_all_app_eq:
  assumes "x y. A x  B x y  f x (m y) = g x y"
  shows "((x : A)  pred_map (λf. f  m) ((y : B x)  C x y)) f
     ((x : A)  (y : (B x :: _  bool))  C x y) g"
  using assms by (simp cong: dep_mono_wrt_pred_codom_iff_cong)

definition "mono :: (('a :: ord)  ('b :: ord))  bool
   (((≤) :: 'a  'a  bool)  ((≤) :: 'b  'b  bool))"

lemma mono_eq_mono_wrt_le [simp]: "(mono :: (('a :: ord)  ('b :: ord))  bool) =
  (((≤) :: 'a  'a  bool)  ((≤) :: 'b  'b  bool))"
  unfolding mono_def by simp

lemma mono_eq_mono_wrt_le_uhint [uhint]:
  assumes "R  (≤) :: 'a  'a  bool"
  and "S  (≤) :: 'b  'b  bool"
  shows "mono :: (('a :: ord)  ('b :: ord))  bool  (R  S)"
  using assms by simp

lemma mono_iff_mono_wrt_le [iff]: "mono f  ((≤)  (≤)) f" by simp

lemma monoI [intro]:
  assumes "x y. x  y  f x  f y"
  shows "mono f"
  using assms by (urule mono_wrt_relI)

lemma monoE [elim]:
  assumes "mono f"
  obtains "x y. x  y  f x  f y"
  using assms by (urule (e) mono_wrt_relE)

lemma monoD:
  assumes "mono f"
  and "x  y"
  shows "f x  f y"
  using assms by (urule mono_wrt_relD)

definition "antimono :: (('a :: ord)  ('b :: ord))  bool
   (((≤) :: 'a  'a  bool)  ((≥) :: 'b  'b  bool))"

lemma antimono_eq_mono_wrt_le_ge [simp]: "(antimono :: (('a :: ord)  ('b :: ord))  bool) =
  (((≤) :: 'a  'a  bool)  ((≥) :: 'b  'b  bool))"
  unfolding antimono_def by simp

lemma antimono_eq_mono_wrt_le_ge_uhint [uhint]:
  assumes "R  (≤) :: 'a  'a  bool"
  and "S  (≥) :: 'b  'b  bool"
  shows "antimono :: (('a :: ord)  ('b :: ord))  bool  (R  S)"
  using assms by simp

lemma antimono_iff_mono_wrt_le_ge [iff]: "antimono f  ((≤)  (≥)) f" by simp

lemma antimonoI [intro]:
  assumes "x y. x  y  f x  f y"
  shows "antimono f"
  by (urule mono_wrt_relI) (urule assms)

lemma antimonoE [elim]:
  assumes "antimono f"
  obtains "x y. x  y  f x  f y"
  using assms by (urule (e) mono_wrt_relE)

lemma antimonoD:
  assumes "antimono f"
  and "x  y"
  shows "f x  f y"
  using assms by (urule mono_wrt_relD)

lemma antimono_Dep_Fun_Rel_rel_left: "antimono (λ(R :: 'a  'b  bool). ((x y  R)  S x y))"
  by (intro antimonoI) auto

lemma antimono_Dep_Fun_Rel_pred_left: "antimono (λ(P :: 'a  bool). ((x : P)  Q x))"
  by (intro antimonoI) auto

lemma antimono_dep_mono_wrt_rel_left: "antimono (λ(R :: 'a  'a  bool). ((x y  R)  S x y))"
  by (intro antimonoI) blast

lemma antimono_dep_mono_wrt_pred_left: "antimono (λ(P :: 'a  bool). ((x : P)  Q x))"
  by (intro antimonoI) blast

lemma Dep_Fun_Rel_rel_if_le_left_if_Dep_Fun_Rel_rel:
  fixes R R' :: "'a  'b  bool"
  assumes "((x y  R)  S x y) f g"
  and "R'  R"
  shows "((x y  R)  S x y) f g"
  using assms by blast

lemma Dep_Fun_Rel_pred_if_le_left_if_Dep_Fun_Rel_pred:
  fixes P P' :: "'a  bool"
  assumes "((x : P)  Q x) f g"
  and "P'  P"
  shows "((x : P')  Q x) f g"
  using assms by blast

lemma dep_mono_wrt_rel_if_le_left_if_dep_mono_wrt_rel:
  fixes R R' :: "'a  'a  bool"
  assumes "((x y  R)  S x y) f"
  and "R'  R"
  shows "((x y  R')  S x y) f"
  using assms by blast

lemma dep_mono_wrt_pred_if_le_left_if_dep_mono_wrt_pred:
  fixes P P' :: "'a  bool"
  assumes "((x : P)  Q x) f"
  and "P'  P"
  shows "((x : P')  Q x) f"
  using assms by blast

lemma mono_Dep_Fun_Rel_rel_right: "mono (λ(S :: 'a  'b  'c  'd  bool). ((x y  R)  S x y))"
  by (intro monoI) blast

lemma mono_Dep_Fun_Rel_pred_right: "mono (λ(Q :: 'a  'b  'c  bool). ((x : P)  Q x))"
  by (intro monoI) blast

lemma mono_dep_mono_wrt_rel_right: "mono (λ(S :: 'a  'a  'b  'b  bool). ((x y  R)  S x y))"
  by (intro monoI) blast

lemma mono_dep_mono_wrt_pred_right: "mono (λ(Q :: 'a  'b  bool). ((x : P)  Q x))"
  by (intro monoI) blast

lemma Dep_Fun_Rel_rel_if_le_right_if_Dep_Fun_Rel_rel:
  assumes "((x y  R)  S x y) f g"
  and "x y. R x y  S x y (f x) (g y)  T x y (f x) (g y)"
  shows "((x y  R)  T x y) f g"
  using assms by (intro Dep_Fun_Rel_relI) blast

lemma Dep_Fun_Rel_pred_if_le_right_if_Dep_Fun_Rel_pred:
  assumes "((x : P)  Q x) f g"
  and "x. P x  Q x (f x) (g x)  T x (f x) (g x)"
  shows "((x : P)  T x) f g"
  using assms by blast

lemma dep_mono_wrt_rel_if_le_right_if_dep_mono_wrt_rel:
  assumes "((x y  R)  S x y) f"
  and "x y. R x y  S x y (f x) (f y)  T x y (f x) (f y)"
  shows "((x y  R)  T x y) f"
  using assms by (intro dep_mono_wrt_relI) blast

lemma dep_mono_wrt_pred_if_le_right_if_dep_mono_wrt_pred:
  assumes "((x : P)  Q x) f"
  and "x. P x  Q x (f x)  T x (f x)"
  shows "((x : P)  T x) f"
  using assms by blast


paragraph ‹Composition›

lemma dep_mono_wrt_rel_compI:
  assumes "((x y  R)  S x y) f"
  and "x y. R x y  ((x' y'  T x y)  U x y x' y') f'"
  and "x y. R x y  S x y (f x) (f y)  T x y (f x) (f y)"
  shows "((x y  R)  U x y (f x) (f y)) (f'  f)"
  using assms by (intro dep_mono_wrt_relI) force

corollary dep_mono_wrt_rel_compI':
  assumes "((x y  R)  S x y) f"
  and "x y. R x y  ((x' y'  S x y)  T x y x' y') f'"
  shows "((x y  R)  T x y (f x) (f y)) (f'  f)"
  using assms by (intro dep_mono_wrt_rel_compI)

lemma dep_mono_wrt_pred_comp_dep_mono_wrt_rel_compI:
  assumes "((x : P)  Q x) f"
  and "x. P x  ((x' y'  R x)  S x x' y') f'"
  and "x. P x  Q x (f x)  R x (f x) (f x)"
  shows "((x : P)  (λy. S x (f x) (f x) y y)) (f'  f)"
  using assms by (intro dep_mono_wrt_predI) force

lemma dep_mono_wrt_pred_comp_dep_mono_wrt_pred_compI:
  assumes "((x : P)  Q x) f"
  and "x. P x  ((x' : R x)  S x x') f'"
  and "x. P x  Q x (f x)  R x (f x)"
  shows "((x : P)  S x (f x)) (f'  f)"
  using assms by (intro dep_mono_wrt_predI) force

corollary dep_mono_wrt_pred_comp_dep_mono_wrt_pred_compI':
  assumes "((x : P)  Q x) f"
  and "x. P x  ((x' : Q x)  S x x') f'"
  shows "((x : P)  S x (f x)) (f'  f)"
  using assms by (intro dep_mono_wrt_pred_comp_dep_mono_wrt_pred_compI)

lemma mono_wrt_rel_top [iff]:
  fixes R :: "'a  'a  bool" and f :: "'a  'b"
  shows "(R  ( :: 'b  'b  bool)) f"
  by auto

lemma mono_wrt_pred_top [iff]:
  fixes P :: "'a  bool" and f :: "'a  'b"
  shows "(P  ( :: 'b  bool)) f"
  by auto

paragraph ‹Instantiations›

lemma mono_wrt_rel_self_id:
  fixes R :: "'a  'a  bool"
  shows "(R  R) (id :: 'a  'a)"
  by auto

lemma mono_wrt_pred_self_id:
  fixes P :: "'a  bool"
  shows "(P  P) (id :: 'a  'a)"
  by auto

lemma mono_dep_mono_wrt_dep_mono_wrt_comp:
  "(((x : (B :: 'b  bool))  C x)  (f : A  B)  (x : A)  C (f x)) (∘)"
  by force

lemma mono_wrt_dep_mono_wrt_dep_fun_map:
  fixes A :: "'a  bool"
  shows "((f : A  B)  ((x : A)  (y : B)  (z : C (f x))  D x y z) 
    (h : (x : B)  C x)  (x : A)  D x (f x) (h (f x))) dep_fun_map"
  by fastforce

lemma mono_wrt_dep_mono_wrt_fun_map:
  fixes A :: "'a  bool"
  shows "((f : A  B)  ((x : C)  D x)  (h : B  C)  (x : A)  D (h (f x))) fun_map"
  by fastforce

lemma mono_in_dom: "mono in_dom" by (intro monoI) fast
lemma mono_in_codom: "mono in_codom" by (intro monoI) fast
lemma mono_in_field: "mono in_field" by (intro monoI) fast
lemma mono_rel_comp: "((≤)  (≤)  (≤)) (∘∘)" by (intro mono_wrt_relI Fun_Rel_relI le_relI) fast
lemma mono_rel_inv: "mono rel_inv" by (intro monoI) fast

lemma mono_rel_restrict_left:
  "((≤)  (≤)  (≤)) (rel_restrict_left :: ('a  'b  bool)  ('a  bool)  'a  'b  bool)"
  by (intro mono_wrt_relI Fun_Rel_relI le_relI) fastforce

lemma mono_rel_restrict_right:
  "((≤)  (≤)  (≤)) (rel_restrict_right :: ('a  'b  bool)  ('b  bool)  'a  'b  bool)"
  by (intro mono_wrt_relI Fun_Rel_relI le_relI) fastforce

lemma mono_ball: "((≥)  (≤)  (≤)) ball" by fast
lemma mono_bex: "((≤)  (≤)  (≤)) bex" by fast

end