Theory Localization_Interface

theory Localization_Interface
  imports
    "HOL-Algebra.Ring_Divisibility"
    "HOL-Algebra.QuotRing"
    Localization_Ring.Localization
begin

section ‹Localization helper lemmas›

text ‹
  The AFP entry theoryLocalization_Ring.Localization develops localizations as
  quotient rings in the HOL-Algebra hierarchy.  For the present development we
  package a small wrapper layer at the level of equality of representatives,
  denominator rescaling, units coming from the multiplicative set, and
  injectivity of the canonical map.
›

context eq_obj_rng_of_frac
begin

lemma fraction_eq_iff_rel:
  assumes "(r, s)  carrier rel"
    and "(r', s')  carrier rel"
  shows "(r |rels) = (r' |rels')  (r, s) .=rel(r', s')"
proof
  from assms have rs: "(r, s)  carrier R × S" and rs': "(r', s')  carrier R × S"
    by (simp_all add: rel_def)
  assume "(r |rels) = (r' |rels')"
  then show "(r, s) .=rel(r', s')"
    using eq_class_to_rel[of r s r' s'] rs rs' by blast
next
  assume hrel: "(r, s) .=rel(r', s')"
  have "class_ofrel(r, s) = class_ofrel(r', s')"
    using equiv_obj_rng_of_frac assms hrel by (rule elem_eq_class)
  then show "(r |rels) = (r' |rels')"
    by (simp add: class_of_to_rel)
qed

lemma fraction_zero_rep [simp]:
  assumes "s  S"
  shows "(𝟬 |rels) = 𝟬rec_rng_of_frac⇙"
  using assms by (rule class_of_zero_rng_of_frac)

lemma fraction_surj:
  assumes "x  carrier rec_rng_of_frac"
  shows "r  carrier R. s  S. x = (r |rels)"
  using assms
  unfolding rec_rng_of_frac_def set_eq_class_of_rng_of_frac_def rel_def
  by auto

lemma fraction_rescale:
  assumes "(r, s)  carrier rel"
    and "s'  S"
  shows "(r |rels) = (s'  r |rels'  s)"
  using assms by (rule simp_in_frac)

lemma fraction_mult_rep:
  assumes rs: "(r, s)  carrier rel"
    and r's': "(r', s')  carrier rel"
  shows "(r |rels) rec_rng_of_frac(r' |rels') =
      (r Rr' |rels Rs')"
proof -
  have hfund:
      "(r |rels) rec_monoid_rng_of_frac(r' |rels') =
        (r Rr' |rels Rs')"
    using mult_rng_of_frac_fundamental_lemma[OF rs r's']
    by simp
  have hmonoid_mult:
      "(r |rels) rec_monoid_rng_of_frac(r' |rels') =
        mult_rng_of_frac (r |rels) (r' |rels')"
    by (simp add: rec_monoid_rng_of_frac_def)
  have "(r |rels) rec_rng_of_frac(r' |rels') =
      mult_rng_of_frac (r |rels) (r' |rels')"
    by (simp only: rec_rng_of_frac_def ring_record_simps)
  also have " = (r |rels) rec_monoid_rng_of_frac(r' |rels')"
    using hmonoid_mult by simp
  also have " = (r Rr' |rels Rs')"
    by (rule hfund)
  finally show ?thesis .
qed

lemma map_mul_fraction:
  assumes a_in: "a  carrier R"
    and rs: "(r, s)  carrier rel"
  shows "rng_to_rng_of_frac a rec_rng_of_frac(r |rels) = (a Rr |rels)"
proof -
  have one_in: "𝟭  S"
    by (rule one_closed)
  have a_rel: "(a, 𝟭)  carrier rel"
    using a_in one_in by (simp add: rel_def)
  have s_in: "s  S"
    using rs by (simp add: rel_def)
  have s_carrier: "s  carrier R"
    using subset s_in by blast
  have one_s: "𝟭 Rs = s"
    using s_carrier by simp
  have "rng_to_rng_of_frac a rec_rng_of_frac(r |rels) = (a |rel𝟭) rec_rng_of_frac(r |rels)"
    by (simp add: rng_to_rng_of_frac_def)
  also have " = (a Rr |rel𝟭 Rs)"
    by (rule fraction_mult_rep[OF a_rel rs])
  also have " = (a Rr |rels)"
    using one_s by simp
  finally show ?thesis .
qed

lemma fraction_mul_map:
  assumes rs: "(r, s)  carrier rel"
    and a_in: "a  carrier R"
  shows "(r |rels) rec_rng_of_fracrng_to_rng_of_frac a = (r Ra |rels)"
proof -
  have one_in: "𝟭  S"
    by (rule one_closed)
  have a_rel: "(a, 𝟭)  carrier rel"
    using a_in one_in by (simp add: rel_def)
  have s_in: "s  S"
    using rs by (simp add: rel_def)
  have s_carrier: "s  carrier R"
    using subset s_in by blast
  have s_one: "s R𝟭 = s"
    using s_carrier by simp
  have "(r |rels) rec_rng_of_fracrng_to_rng_of_frac a = (r |rels) rec_rng_of_frac(a |rel𝟭)"
    by (simp add: rng_to_rng_of_frac_def)
  also have " = (r Ra |rels R𝟭)"
    by (rule fraction_mult_rep[OF rs a_rel])
  also have " = (r Ra |rels)"
    using s_one by simp
  finally show ?thesis .
qed

lemma fraction_eq_iff_cross_multiply:
  assumes rs: "(r, s)  carrier rel"
    and rs': "(r', s')  carrier rel"
    and zero_notin: "𝟬  S"
    and no_zero_div: "a  carrier R. b  carrier R. a  b = 𝟬  a = 𝟬  b = 𝟬"
  shows "(r |rels) = (r' |rels')  s' Rr = s Rr'"
proof (intro iffI)
  from rs rs' have r_in: "r  carrier R" and s_in: "s  S"
    and r'_in: "r'  carrier R" and s'_in: "s'  S"
    by (simp_all add: rel_def)
  have s_carrier: "s  carrier R" and s'_carrier: "s'  carrier R"
    using s_in s'_in subset rev_subsetD by auto
  have lhs_in: "s' Rr  carrier R"
    using s'_carrier r_in by auto
  have rhs_in: "s Rr'  carrier R"
    using s_carrier r'_in by auto
  assume eq_frac: "(r |rels) = (r' |rels')"
    have hrel: "(r, s) .=rel(r', s')"
      using fraction_eq_iff_rel[OF rs rs'] eq_frac by blast
    then obtain t where t_in: "t  S" and t_zero: "t  ((s' Rr) R(s Rr')) = 𝟬"
      unfolding rel_def by auto
    have t_carrier: "t  carrier R"
      using t_in subset rev_subsetD by auto
    have diff_in: "(s' Rr) R(s Rr')  carrier R"
      using lhs_in rhs_in by auto
    have "t = 𝟬  (s' Rr) R(s Rr') = 𝟬"
      using no_zero_div t_carrier diff_in t_zero by blast
    moreover have "t  𝟬"
      using t_in zero_notin by auto
    ultimately have "(s' Rr) R(s Rr') = 𝟬"
      by auto
    then have "((s' Rr) R(s Rr')) R(s Rr') =
        𝟬 R(s Rr')"
      by simp
    then have "(s' Rr) R((R(s Rr')) R(s Rr')) =
        s Rr'"
      using lhs_in rhs_in by (simp add: a_minus_def a_assoc)
    have inv_cancel: "(R(s Rr')) R(s Rr') = 𝟬"
      using rhs_in by (rule l_neg)
    then have "(s' Rr) R((R(s Rr')) R(s Rr')) =
        (s' Rr) R𝟬"
      by simp
    then have "(s' Rr) R𝟬 = s Rr'"
      using (s' Rr) R((R(s Rr')) R(s Rr')) =
        s Rr'
      by simp
  then show "s' Rr = s Rr'"
    using lhs_in by (simp add: r_zero)
next
  assume cross_mul: "s' Rr = s Rr'"
  from rs rs' have r_in': "r  carrier R" and s'_in': "s'  S"
    by (simp_all add: rel_def)
  have lhs_in': "s' Rr  carrier R"
  proof -
    have "s'  carrier R"
      using s'_in' subset rev_subsetD by auto
    then show ?thesis
      using r_in' by auto
  qed
  have diff_zero: "(s' Rr) R(s Rr') = 𝟬"
  proof -
    have "(s' Rr) R(s Rr') = (s' Rr) R(s' Rr)"
      using cross_mul by simp
    also have " = (s' Rr) R(R(s' Rr))"
      by (simp add: a_minus_def)
    also have " = 𝟬"
      using lhs_in' by (rule r_neg)
    finally show ?thesis .
  qed
  have "(r, s) .=rel(r', s')"
  proof -
    have "𝟭  S"
      by (rule one_closed)
    moreover have "𝟭  ((s' Rr) R(s Rr')) = 𝟬"
      using diff_zero by simp
    ultimately show ?thesis
      unfolding rel_def using rs rs' by auto
  qed
  then show "(r |rels) = (r' |rels')"
    using fraction_eq_iff_rel[OF rs rs'] by blast
qed

lemma fraction_eq_zero_iff:
  assumes rs: "(r, s)  carrier rel"
    and zero_notin: "𝟬  S"
    and no_zero_div: "a  carrier R. b  carrier R. a  b = 𝟬  a = 𝟬  b = 𝟬"
  shows "(r |rels) = 𝟬rec_rng_of_frac r = 𝟬"
proof
  from rs have s_in: "s  S"
    by (simp add: rel_def)
  have s_carrier: "s  carrier R"
    using subset s_in by blast
  from rs have r_in: "r  carrier R"
    by (simp add: rel_def)
  have zero_rel: "(𝟬, 𝟭)  carrier rel"
    by (simp add: rel_def one_closed)
  assume hzero: "(r |rels) = 𝟬rec_rng_of_frac⇙"
  have "(r |rels) = (𝟬 |rel𝟭)"
    using hzero by (simp add: class_of_zero_rng_of_frac[OF one_closed])
  then have "𝟭 Rr = s R𝟬"
    using fraction_eq_iff_cross_multiply[OF rs zero_rel zero_notin no_zero_div]
    by simp
  then have "r = s R𝟬"
    using r_in by simp
  also have " = 𝟬"
    using s_carrier by simp
  finally show "r = 𝟬" .
next
  assume "r = 𝟬"
  then have r_zero: "r = 𝟬" .
  have s_in: "s  S"
    using rs by (simp add: rel_def)
  from r_zero s_in show "(r |rels) = 𝟬rec_rng_of_frac⇙"
    by simp
qed

lemma map_eq_zero_iff:
  assumes a_in: "a  carrier R"
    and zero_notin: "𝟬  S"
    and no_zero_div: "a'  carrier R. b'  carrier R. a'  b' = 𝟬  a' = 𝟬  b' = 𝟬"
  shows "rng_to_rng_of_frac a = 𝟬rec_rng_of_frac a = 𝟬"
proof -
  have a_rel: "(a, 𝟭)  carrier rel"
    using a_in one_closed by (simp add: rel_def)
  show ?thesis
    using fraction_eq_zero_iff[OF a_rel zero_notin no_zero_div]
    by (simp add: rng_to_rng_of_frac_def)
qed

lemma dvd_map_iff:
  assumes a_in: "a  carrier R"
    and b_in: "b  carrier R"
    and zero_notin: "𝟬  S"
    and no_zero_div: "a'  carrier R. b'  carrier R. a'  b' = 𝟬  a' = 𝟬  b' = 𝟬"
  shows "rng_to_rng_of_frac a dividesrec_rng_of_fracrng_to_rng_of_frac b  (s  S. a dividesR(s Rb))"
proof
  assume hdiv: "rng_to_rng_of_frac a dividesrec_rng_of_fracrng_to_rng_of_frac b"
  then obtain x where x_mem: "x  carrier rec_rng_of_frac"
    and hx: "rng_to_rng_of_frac b = rng_to_rng_of_frac a rec_rng_of_fracx"
    unfolding factor_def by blast
  from fraction_surj[OF x_mem] obtain c where c_in: "c  carrier R"
    and hs: "s  S. x = (c |rels)"
    by blast
  from hs obtain s where s_in: "s  S" and x_def: "x = (c |rels)"
    by blast
  have b_rel: "(b, 𝟭)  carrier rel"
    using b_in one_closed by (simp add: rel_def)
  have cs_rel: "(c, s)  carrier rel"
    using c_in s_in by (simp add: rel_def)
  have ac_rel: "(a Rc, s)  carrier rel"
    using a_in c_in s_in by (simp add: rel_def)
  have "(b |rel𝟭) = (a Rc |rels)"
  proof -
    have h1: "rng_to_rng_of_frac b = rng_to_rng_of_frac a rec_rng_of_frac(c |rels)"
      using hx x_def by simp
    have h2: "rng_to_rng_of_frac a rec_rng_of_frac(c |rels) = (a Rc |rels)"
      using map_mul_fraction[OF a_in cs_rel] by simp
    from h1 h2 show ?thesis
      by (simp add: rng_to_rng_of_frac_def)
  qed
  then have "s Rb = 𝟭 R(a Rc)"
    using fraction_eq_iff_cross_multiply[OF b_rel ac_rel zero_notin no_zero_div]
    by simp
  then have "s Rb = a Rc"
    using a_in c_in by simp
  then have "a dividesR(s Rb)"
    unfolding factor_def using c_in by blast
  then show "s  S. a dividesR(s Rb)"
    using s_in by blast
next
  assume hdiv: "s  S. a dividesR(s Rb)"
  then obtain s where s_in: "s  S" and hsab: "a dividesR(s Rb)"
    by blast
  then obtain c where c_in: "c  carrier R" and hc: "s Rb = a Rc"
    unfolding factor_def by blast
  have cs_rel: "(c, s)  carrier rel"
    using c_in s_in by (simp add: rel_def)
  have ac_rel: "(a Rc, s)  carrier rel"
    using a_in c_in s_in by (simp add: rel_def)
  have b_rel: "(b, 𝟭)  carrier rel"
    using b_in one_closed by (simp add: rel_def)
  have eq_frac: "(b |rel𝟭) = (a Rc |rels)"
  proof -
    have "s Rb = 𝟭 R(a Rc)"
      using hc a_in c_in by simp
    then show ?thesis
      using fraction_eq_iff_cross_multiply[OF b_rel ac_rel zero_notin no_zero_div]
      by blast
  qed
  have frac_mem: "(c |rels)  carrier rec_rng_of_frac"
    using cs_rel unfolding rec_rng_of_frac_def set_eq_class_of_rng_of_frac_def
    by auto
  have "rng_to_rng_of_frac b = rng_to_rng_of_frac a rec_rng_of_frac(c |rels)"
  proof -
    have h1: "rng_to_rng_of_frac b = (b |rel𝟭)"
      by (simp add: rng_to_rng_of_frac_def)
    have h2: "(b |rel𝟭) = (a Rc |rels)"
      using eq_frac by simp
    have h3: "rng_to_rng_of_frac a rec_rng_of_frac(c |rels) = (a Rc |rels)"
      using map_mul_fraction[OF a_in cs_rel] by simp
    from h1 h2 h3 show ?thesis
      by simp
  qed
  then show "rng_to_rng_of_frac a dividesrec_rng_of_fracrng_to_rng_of_frac b"
    unfolding factor_def using frac_mem by blast
qed

lemma image_submonoid_is_unit:
  assumes "x  rng_to_rng_of_frac ` S"
  shows "x  Units rec_rng_of_frac"
  using assms by (rule Im_rng_to_rng_of_frac_unit)

lemma map_submonoid_elem_is_unit:
  assumes "s  S"
  shows "rng_to_rng_of_frac s  Units rec_rng_of_frac"
  using assms image_submonoid_is_unit by blast

lemma map_unit_is_unit:
  assumes u_unit: "u  Units R"
  shows "rng_to_rng_of_frac u  Units rec_rng_of_frac"
proof -
  have u_in: "u  carrier R"
    using u_unit by blast
  have inv_u_in: "inv u  carrier R"
    using u_unit by blast
  have map_u_in: "rng_to_rng_of_frac u  carrier rec_rng_of_frac"
    using ring_hom_closed[OF rng_to_rng_of_frac_is_ring_hom u_in] .
  have map_inv_u_in: "rng_to_rng_of_frac (inv u)  carrier rec_rng_of_frac"
    using ring_hom_closed[OF rng_to_rng_of_frac_is_ring_hom inv_u_in] .
  have left_inv:
      "rng_to_rng_of_frac u rec_rng_of_fracrng_to_rng_of_frac (inv u) =
        𝟭rec_rng_of_frac⇙"
  proof -
    have "rng_to_rng_of_frac u rec_rng_of_fracrng_to_rng_of_frac (inv u) =
        rng_to_rng_of_frac (u Rinv u)"
      using ring_hom_mult[OF rng_to_rng_of_frac_is_ring_hom u_in inv_u_in]
      by simp
    also have " = rng_to_rng_of_frac 𝟭"
      using u_unit by simp
    also have " = 𝟭rec_rng_of_frac⇙"
      using ring_hom_one[OF rng_to_rng_of_frac_is_ring_hom] .
    finally show ?thesis .
  qed
  have right_inv:
      "rng_to_rng_of_frac (inv u) rec_rng_of_fracrng_to_rng_of_frac u =
        𝟭rec_rng_of_frac⇙"
  proof -
    have "rng_to_rng_of_frac (inv u) rec_rng_of_fracrng_to_rng_of_frac u =
        rng_to_rng_of_frac (inv u Ru)"
      using ring_hom_mult[OF rng_to_rng_of_frac_is_ring_hom inv_u_in u_in]
      by simp
    also have " = rng_to_rng_of_frac 𝟭"
      using u_unit by simp
    also have " = 𝟭rec_rng_of_frac⇙"
      using ring_hom_one[OF rng_to_rng_of_frac_is_ring_hom] .
    finally show ?thesis .
  qed
  show ?thesis
    unfolding Units_def
    using map_u_in map_inv_u_in left_inv right_inv by blast
qed

lemma fraction_unit_numerator_is_unit:
  assumes u_unit: "u  Units R"
    and s_in: "s  S"
  shows "(u |rels)  Units rec_rng_of_frac"
proof -
  have u_in: "u  carrier R"
    using Units_closed[OF u_unit] .
  have s_carrier: "s  carrier R"
    using subset s_in by blast
  have u_rel: "(u, 𝟭)  carrier rel"
    using u_in one_closed by (simp add: rel_def)
  have one_rel: "(𝟭, s)  carrier rel"
    using s_in by (simp add: rel_def)
  have frac_eq':
      "rng_to_rng_of_frac u rec_rng_of_frac(𝟭 |rels) =
        (u |rels)"
  proof -
    have "rng_to_rng_of_frac u rec_rng_of_frac(𝟭 |rels) =
        (u |rel𝟭) rec_rng_of_frac(𝟭 |rels)"
      by (simp add: rng_to_rng_of_frac_def)
    also have " = (u R𝟭 |rel𝟭 Rs)"
      by (rule fraction_mult_rep[OF u_rel one_rel])
    also have " = (u |rels)"
      using u_in s_carrier by simp
    finally show ?thesis .
  qed
  have frac_eq:
      "(u |rels) =
        rng_to_rng_of_frac u rec_rng_of_frac(𝟭 |rels)"
    using frac_eq' by simp
  have map_unit: "rng_to_rng_of_frac u  Units rec_rng_of_frac"
    using u_unit by (rule map_unit_is_unit)
  have denom_unit: "(𝟭 |rels)  Units rec_rng_of_frac"
  proof -
    have s_carrier: "s  carrier R"
      using subset s_in by blast
    have s_rel: "(s, 𝟭)  carrier rel"
      using s_carrier one_closed by (simp add: rel_def)
    have left_inv:
        "(𝟭 |rels) rec_rng_of_fracrng_to_rng_of_frac s =
          𝟭rec_rng_of_frac⇙"
    proof -
      have "(𝟭 |rels) rec_rng_of_fracrng_to_rng_of_frac s =
          (𝟭 |rels) rec_rng_of_frac(s |rel𝟭)"
        by (simp add: rng_to_rng_of_frac_def)
      also have " = (𝟭 Rs |rels R𝟭)"
        by (rule fraction_mult_rep[OF one_rel s_rel])
      also have " = (𝟭 |rel𝟭)"
      proof -
        have one_rel': "(𝟭, 𝟭)  carrier rel"
          using one_closed by (simp add: rel_def)
        have "(𝟭 |rel𝟭) = (s R𝟭 |rels R𝟭)"
          by (rule fraction_rescale[OF one_rel' s_in])
        then show ?thesis
          using s_carrier by simp
      qed
      also have " = 𝟭rec_rng_of_frac⇙"
        by (simp only: rec_rng_of_frac_def ring_record_simps)
      finally show ?thesis .
    qed
    have right_inv:
        "rng_to_rng_of_frac s rec_rng_of_frac(𝟭 |rels) =
          𝟭rec_rng_of_frac⇙"
    proof -
      have "rng_to_rng_of_frac s rec_rng_of_frac(𝟭 |rels) =
          (s |rel𝟭) rec_rng_of_frac(𝟭 |rels)"
        by (simp add: rng_to_rng_of_frac_def)
      also have " = (s R𝟭 |rel𝟭 Rs)"
        by (rule fraction_mult_rep[OF s_rel one_rel])
      also have " = (𝟭 |rel𝟭)"
      proof -
        have one_rel': "(𝟭, 𝟭)  carrier rel"
          using one_closed by (simp add: rel_def)
        have "(𝟭 |rel𝟭) = (s R𝟭 |rels R𝟭)"
          by (rule fraction_rescale[OF one_rel' s_in])
        then show ?thesis
          using s_carrier by simp
      qed
      also have " = 𝟭rec_rng_of_frac⇙"
        by (simp only: rec_rng_of_frac_def ring_record_simps)
      finally show ?thesis .
    qed
    have frac_in: "(𝟭 |rels)  carrier rec_rng_of_frac"
    proof -
      have one_s_rel: "(𝟭, s)  carrier rel"
        using s_in by (simp add: rel_def)
      show ?thesis
        using one_s_rel
        unfolding rec_rng_of_frac_def set_eq_class_of_rng_of_frac_def
        by auto
    qed
    have s_carrier: "s  carrier R"
      using s_in subset rev_subsetD by blast
    have map_s_in: "rng_to_rng_of_frac s  carrier rec_rng_of_frac"
      using ring_hom_closed[OF rng_to_rng_of_frac_is_ring_hom s_carrier] .
    show ?thesis
      unfolding Units_def using frac_in map_s_in left_inv right_inv by blast
  qed
  show ?thesis
  proof -
    have "rng_to_rng_of_frac u rec_rng_of_frac(𝟭 |rels)  Units rec_rng_of_frac"
      by (rule monoid.Units_m_closed[OF ring.is_monoid[OF rng_rng_of_frac] map_unit denom_unit])
    then show ?thesis
      using frac_eq by simp
  qed
qed

lemma map_inj_on:
  assumes "𝟬  S"
    and "a  carrier R. b  carrier R. a  b = 𝟬  a = 𝟬  b = 𝟬"
  shows "inj_on rng_to_rng_of_frac (carrier R)"
proof -
  have "a_kernel R rec_rng_of_frac rng_to_rng_of_frac = {𝟬}"
    using assms by (rule rng_to_rng_of_frac_without_zero_div_is_inj)
  then show ?thesis
    using ring_hom_ring.trivial_ker_imp_inj[
        OF ring_hom_ringI2[OF ring_axioms rng_rng_of_frac rng_to_rng_of_frac_is_ring_hom]
      ]
    by blast
qed

end

end