Theory Min_Max_Least_Greatest_Set

theory Min_Max_Least_Greatest_Set
  imports
    Relation_Reachability
begin

section ‹Minimal and maximal elements›

text ‹If the binary relation is a strict partial order, then non-reachability corresponds to
minimality and non-reaching correspond to maximality.›

definition is_minimal_in_set_wrt :: "('a  'a  bool)  'a set  'a  bool" where
  "transp_on X R  asymp_on X R  is_minimal_in_set_wrt R X = non_reachable_wrt R X"

definition is_maximal_in_set_wrt :: "('a  'a  bool)  'a set  'a  bool" where
  "transp_on X R  asymp_on X R  is_maximal_in_set_wrt R X = non_reaching_wrt R X"

context
  fixes X R
  assumes
    trans: "transp_on X R" and
    asym: "asymp_on X R"
begin


subsection ‹Conversions›

lemma is_minimal_in_set_wrt_iff:
  "is_minimal_in_set_wrt R X x  x  X  (y  X. y  x  ¬ R y x)"
  using trans asym is_minimal_in_set_wrt_def[unfolded non_reachable_wrt_iff] by metis

lemma is_maximal_in_set_wrt_iff:
  "is_maximal_in_set_wrt R X x  x  X  (y  X. y  x  ¬ R x y)"
  using trans asym is_maximal_in_set_wrt_def[unfolded non_reaching_wrt_iff] by metis

subsection ‹Existence›

lemma ex_minimal_in_set_wrt:
  "finite X  X  {}  x. is_minimal_in_set_wrt R X x"
  using trans asym ex_non_reachable_wrt is_minimal_in_set_wrt_def by metis

lemma ex_maximal_in_set_wrt:
  "finite X  X  {}  m. is_maximal_in_set_wrt R X m"
  using trans asym is_maximal_in_set_wrt_def ex_non_reaching_wrt by metis

end


subsection ‹Miscellaneous›

lemma is_minimal_in_set_wrt_filter_iff:
  fixes X R
  assumes trans: "transp_on {y  X. P y} R" and asym: "asymp_on {y  X. P y} R"
  shows "is_minimal_in_set_wrt R {y  X. P y} x  x  X  P x  (y  X - {x}. P y  ¬ R y x)"
proof -
  have "is_minimal_in_set_wrt R {y  X. P y} x  non_reachable_wrt R {y  X. P y} x"
    using trans asym is_minimal_in_set_wrt_def by metis
  also have "  x  X  P x  (y  X - {x}. P y  ¬ R y x)"
    unfolding non_reachable_wrt_filter_iff ..
  finally show ?thesis .
qed

lemma is_minimal_in_set_wrt_insertI:
  assumes
    trans: "transp_on (insert y X) R" and
    asym: "asymp_on (insert y X) R" and
    "R y x" and
    x_min: "is_minimal_in_set_wrt R X x"
  shows "is_minimal_in_set_wrt R (insert y X) y"
  by (metis assms(3) asym asymp_on_subset is_minimal_in_set_wrt_def trans
      non_reachable_wrt_insert_wrtI subset_insertI transp_on_subset x_min)


section ‹Least and greatest elements›

text ‹If the binary relation is a strict total ordering, then an element reaching all others is a
least element and an element reachable by all others is a greatest element.›

definition is_least_in_set_wrt :: "('a  'a  bool)  'a set  'a  bool" where
  "transp_on X R  asymp_on X R  totalp_on X R 
    is_least_in_set_wrt R X = reaching_all_wrt R X"

definition is_greatest_in_set_wrt :: "('a  'a  bool)  'a set  'a  bool" where
  "transp_on X R  asymp_on X R  totalp_on X R 
    is_greatest_in_set_wrt R X = reachable_by_all_wrt R X"

context
  fixes X R
  assumes
    trans: "transp_on X R" and
    asym: "asymp_on X R" and
    tot: "totalp_on X R"
begin


subsection ‹Conversions›

lemma is_least_in_set_wrt_iff:
  "is_least_in_set_wrt R X x  x  X  (y  X. y  x  R x y)"
  using trans asym tot is_least_in_set_wrt_def[unfolded reaching_all_wrt_iff] by metis

lemma is_greatest_in_set_wrt_iff:
  "is_greatest_in_set_wrt R X x  x  X  (y  X. y  x  R y x)"
  using trans asym tot is_greatest_in_set_wrt_def[unfolded reachable_by_all_wrt_iff] by metis

lemma is_minimal_in_set_wrt_eq_is_least_in_set_wrt:
  "is_minimal_in_set_wrt R X = is_least_in_set_wrt R X"
  using trans asym tot non_reachable_wrt_eq_reaching_all_wrt
    is_minimal_in_set_wrt_def is_least_in_set_wrt_def
  by metis

lemma is_maximal_in_set_wrt_eq_is_greatest_in_set_wrt:
  "is_maximal_in_set_wrt R X = is_greatest_in_set_wrt R X"
  using trans asym tot non_reaching_wrt_eq_reachable_by_all_wrt
    is_maximal_in_set_wrt_def is_greatest_in_set_wrt_def
  by metis

subsection ‹Uniqueness›

lemma Uniq_is_least_in_set_wrt:
  "1x. is_least_in_set_wrt R X x"
  using trans asym tot is_least_in_set_wrt_def Uniq_reaching_all_wrt by metis

lemma Uniq_is_greatest_in_set_wrt:
  "1x. is_greatest_in_set_wrt R X x"
  using trans asym tot is_greatest_in_set_wrt_def Uniq_reachable_by_all_wrt by metis


subsection ‹Existence›

lemma ex_least_in_set_wrt:
  "finite X  X  {}  x. is_least_in_set_wrt R X x"
  using trans asym tot is_least_in_set_wrt_def ex_reaching_all_wrt by metis

lemma ex_greatest_in_set_wrt:
  "finite X  X  {}  x. is_greatest_in_set_wrt R X x"
  using trans asym tot is_greatest_in_set_wrt_def ex_reachable_by_all_wrt by metis

lemma ex1_least_in_set_wrt:
  "finite X  X  {}  ∃!x. is_least_in_set_wrt R X x"
  using Uniq_is_least_in_set_wrt ex_least_in_set_wrt by (metis Uniq_def)

lemma ex1_greatest_in_set_wrt:
  "finite X  X  {}  ∃!x. is_greatest_in_set_wrt R X x"
  using Uniq_is_greatest_in_set_wrt ex_greatest_in_set_wrt by (metis Uniq_def)

end


section ‹Hide stuff›

text ‹We restrict the public interface to ease future internal changes.›

hide_fact is_minimal_in_set_wrt_def is_maximal_in_set_wrt_def
hide_fact is_least_in_set_wrt_def is_greatest_in_set_wrt_def


section ‹Integration in type classes›

abbreviation (in order) is_minimal_in_set where
  "is_minimal_in_set  is_minimal_in_set_wrt (<)"

abbreviation (in order) is_maximal_in_set where
  "is_maximal_in_set  is_maximal_in_set_wrt (<)"

lemmas (in order) is_minimal_in_set_iff =
  is_minimal_in_set_wrt_iff[OF transp_on_less asymp_on_less]

lemmas (in order) is_maximal_in_set_iff =
  is_maximal_in_set_wrt_iff[OF transp_on_less asymp_on_less]

lemmas (in order) ex_minimal_in_set =
  ex_minimal_in_set_wrt[OF transp_on_less asymp_on_less]

lemmas (in order) ex_maximal_in_set =
  ex_maximal_in_set_wrt[OF transp_on_less asymp_on_less]

lemmas (in order) is_minimal_in_set_filter_iff =
  is_minimal_in_set_wrt_filter_iff[OF transp_on_less asymp_on_less]


abbreviation (in linorder) is_least_in_set where
  "is_least_in_set  is_least_in_set_wrt (<)"

abbreviation (in linorder) is_greatest_in_set where
  "is_greatest_in_set  is_greatest_in_set_wrt (<)"

lemmas (in linorder) is_least_in_set_iff =
  is_least_in_set_wrt_iff[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) is_greatest_in_set_iff =
  is_greatest_in_set_wrt_iff[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) is_minimal_in_set_eq_is_least_in_set =
  is_minimal_in_set_wrt_eq_is_least_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) is_maximal_in_set_eq_is_greatest_in_set =
  is_maximal_in_set_wrt_eq_is_greatest_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) Uniq_is_least_in_set[intro] =
  Uniq_is_least_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) Uniq_is_greatest_in_set[intro] =
  Uniq_is_greatest_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) ex_least_in_set =
  ex_least_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) ex_greatest_in_set =
  ex_greatest_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) ex1_least_in_set =
  ex1_least_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

lemmas (in linorder) ex1_greatest_in_set =
  ex1_greatest_in_set_wrt[OF transp_on_less asymp_on_less totalp_on_less]

end