Theory Binary_Relations_Wellfounded

✐‹creator "Kevin Kappelmann"›
✐‹creator "Niklas Krofta"›
subsubsection ‹Well-Founded Relations›
theory Binary_Relations_Wellfounded
  imports
    Functions_Monotone
begin

consts wellfounded_on :: "'a  'b  bool"

overloading
  wellfounded_on_pred  "wellfounded_on :: ('a  bool)  ('a  'a  bool)  bool"
begin
  definition "wellfounded_on_pred (P :: 'a  bool) (R :: 'a  'a  bool)
     Q. (x : P. Q x)  (m : P. Q m  (y : P. R y m  ¬(Q y)))"
end

lemma wellfounded_onI:
  assumes "Q x. P x  Q x  m : P. Q m  (y : P. R y m  ¬(Q y))"
  shows "wellfounded_on P R"
  using assms unfolding wellfounded_on_pred_def by blast

lemma wellfounded_onE:
  assumes "wellfounded_on P R" "P x" "Q x"
  obtains m where "P m" "Q m" "y. P y  R y m  ¬(Q y)"
proof -
  from assms obtain m where "P m" "Q m" "y : P. R y m  ¬(Q y)"
    unfolding wellfounded_on_pred_def by auto
  then show ?thesis using that by blast
qed

lemma wellfounded_on_induct [consumes 1, case_names step]:
  assumes "wellfounded_on P R" "P z"
  assumes step: "x. P x  (y. P y  R y x  Q y)  Q x"
  shows "Q z"
proof (rule ccontr)
  assume "¬(Q z)"
  then obtain m where "P m" "¬(Q m)" "y. P y  R y m  Q y"
    using assms by (blast elim!: wellfounded_onE[where Q = "λx. ¬(Q x)"])
  then show "False" using step by auto
qed

lemma wellfounded_on_rel_map_if_mono_wrt_pred_if_wellfounded_on:
  fixes A :: "'a  bool" and B :: "'b  bool"
  assumes wf: "wellfounded_on A R"
  and "(B  A) f"
  shows "wellfounded_on B (rel_map f R)"
proof (intro wellfounded_onI)
  fix Q and x :: 'b assume "B x" "Q x"
  moreover define U where "U  has_inverse_on (B  Q) f"
  ultimately have "A (f x)" "U (f x)" using (B  A) f by auto
  then obtain mU where "A mU" "U mU" and min: "a. A a  R a mU  ¬(U a)"
    using wf by (blast elim!: wellfounded_onE)
  from U mU obtain mQ where "B mQ" "f mQ = mU" "Q mQ" unfolding U_def by blast
  have "¬(Q b)" if "B b" "rel_map f R b mQ" for b
  proof -
    from that have "R (f b) mU" using f mQ = mU by auto
    then have "¬(U (f b))" using B b (B  A) f min by blast
    then show ?thesis unfolding U_def using B b by blast
  qed
  then show "m : B. Q m  (b : B. rel_map f R b m  ¬(Q b))" using B mQ Q mQ by blast
qed

corollary wellfounded_on_if_le_pred_if_wellfounded_on:
  fixes P :: "'a  bool" and R :: "'a  'a  bool"
  assumes "wellfounded_on P R" "Q  P"
  shows "wellfounded_on Q R"
proof -
  have "(Q  P) id" using Q  P by force
  then have "wellfounded_on Q (rel_map id R)"
    using assms wellfounded_on_rel_map_if_mono_wrt_pred_if_wellfounded_on by blast
  then show ?thesis by simp
qed

lemma wellfounded_on_if_le_rel_if_wellfounded_on:
  fixes P :: "'a  bool" and R :: "'a  'a  bool"
  assumes "wellfounded_on P R" "S  R"
  shows "wellfounded_on P S"
proof (intro wellfounded_onI)
  fix Q and x :: 'a assume "P x" "Q x"
  then obtain m where "P m" "Q m" "y. P y  R y m  ¬ Q y"
    using assms by (force elim!: wellfounded_onE)
  then show "m : P. Q m  (y : P. S y m  ¬ Q y)" using S  R by blast
qed

corollary antimono_wellfounded_on:
  "((≤)  (≤)  (≥)) (wellfounded_on :: ('a  bool)  ('a  'a  bool)  bool)"
  using wellfounded_on_if_le_pred_if_wellfounded_on wellfounded_on_if_le_rel_if_wellfounded_on
  by (intro mono_wrt_relI Fun_Rel_relI) blast


consts wellfounded :: "'a  bool"

overloading
  wellfounded  "wellfounded :: ('a  'a  bool)  bool"
begin
  definition "(wellfounded :: ('a  'a  bool)  bool)  wellfounded_on ( :: 'a  bool)"
end

lemma wellfounded_eq_wellfounded_on:
  "(wellfounded :: ('a  'a  bool)  _) = wellfounded_on ( :: 'a  bool)"
  unfolding wellfounded_def ..

lemma wellfounded_eq_wellfounded_on_uhint [uhint]:
  "P  ( :: 'a  bool)  (wellfounded :: ('a  'a  bool)  _)  wellfounded_on P"
  by (simp add: wellfounded_eq_wellfounded_on)

lemma wellfoundedI [intro]:
  assumes "Q x. Q x  (m : Q. y. R y m  ¬(Q y))"
  shows "wellfounded R"
  by (urule wellfounded_onI) (use assms in fastforce)

lemma wellfoundedE:
  assumes "wellfounded R" "Q x"
  obtains m where "Q m" "y. R y m  ¬(Q y)"
  by (urule wellfounded_onE) (urule assms | simp)+

lemma wellfounded_on_if_wellfounded:
  fixes P :: "'a  bool" and R :: "'a  'a  bool"
  assumes "wellfounded R"
  shows "wellfounded_on P R"
  using assms by (urule wellfounded_on_if_le_pred_if_wellfounded_on) auto

lemma wellfounded_induct [consumes 1, case_names step]:
  assumes "wellfounded R"
  assumes "x. (y. R y x  Q y)  Q x"
  shows "Q x"
  using assms(1) by (urule wellfounded_on_induct) (use assms(2-) in auto)

lemma wellfounded_rel_restrict_if_wellfounded_on:
  assumes "wellfounded_on P R"
  shows "wellfounded RP⇙"
proof (intro wellfoundedI)
  fix Q and x :: 'a assume "Q x"
  show "m : Q. y. RPy m  ¬(Q y)"
  proof (cases "s : P. Q s")
    case True
    then show ?thesis using assms by (fast elim!: wellfounded_onE)
  next
    case False
    then show ?thesis using Q x by blast
  qed
qed


end