Theory Preliminaries_LSI

theory Preliminaries_LSI
  imports "HOL-Library.Rewrite" "HOL-Analysis.Analysis"
begin

context order_topology
begin

lemma
  assumes "a < b" 
  shows at_within_Ioo_at_right: "at a within {a<..<b} = at_right a" and
    at_within_Ioo_at_left: "at b within {a<..<b} = at_left b"
    using assms at_within_nhd
    apply (metis inf.right_idem open_lessThan greaterThanLessThan_eq lessThan_iff)
  using assms at_within_nhd
  by (smt (verit, ccfv_SIG) inf.idem inf_aci
      greaterThanLessThan_def greaterThan_iff open_greaterThan)

end

(* subsubsection ‹Intersection› in Set_Interval.thy *)
lemma Int_atLeastAtMost_Unbounded[simp]: "{a..} Int {..b} = {a..b}"
  by auto

lemma Int_greaterThanAtMost_Unbounded[simp]: "{a<..} Int {..b} = {a<..b}"
  by auto

lemma Int_atLeastLessThan_Unbounded[simp]: "{a..} Int {..<b} = {a..<b}"
  by auto

lemma Int_greaterThanLessThan_Unbounded[simp]: "{a<..} Int {..<b} = {a<..<b}"
  by auto

(* supplementary lemmas in Abstract_Topology_2.thy *)

lemma constant_on_empty[simp]: "f constant_on {}"
  by (simp add: constant_on_def)

lemma constant_on_Un:
  assumes "f constant_on A" "f constant_on B" "A  B  {}"
  shows "f constant_on A  B"
proof -
  from assms obtain c where "c  A  B" by auto
  with assms have "x. x  A  B  f x = f c" unfolding constant_on_def by auto
  thus ?thesis unfolding constant_on_def by simp
qed

(* analogue for lemma differentiable_transform_within *)
lemma differentiable_transform_open:
  assumes "f differentiable (at x)"
    and "x  s"
    and "open s"
    and "x'. x's  f x' = g x'"
  shows "g differentiable (at x)"
  using assms has_derivative_transform_within_open at_within_open unfolding differentiable_def
  by blast

lemma differentiable_eq_field_differentiable_real:
  fixes f :: "real  real"
  shows "f differentiable F  f field_differentiable F"
  unfolding field_differentiable_def differentiable_def has_real_derivative
  using has_real_derivative_iff by presburger

lemma differentiable_on_eq_field_differentiable_real:
  fixes f :: "real  real"
  shows "f differentiable_on s  (xs. f field_differentiable (at x within s))"
  unfolding differentiable_on_def using differentiable_eq_field_differentiable_real by simp

lemma set_borel_measurable_UNIV[simp]:
  fixes f :: "'a :: real_vector  real"
  shows "set_borel_measurable M UNIV f  f  borel_measurable M"
  unfolding set_borel_measurable_def by simp

lemma deriv_measurable_real:
  fixes f :: "real  real"
  assumes "f differentiable_on S" "open S" "f  borel_measurable borel"
  shows "set_borel_measurable borel S (deriv f)"
proof -
  have "x. x  S  deriv f x = lim (λi. (f (x + 1 / Suc i) - f x) / (1 / Suc i))"
  proof -
    fix x assume x_S: "x  S"
    hence "f field_differentiable (at x within S)"
      using differentiable_on_eq_field_differentiable_real assms by simp
    hence "(f has_field_derivative deriv f x) (at x)"
      using assms DERIV_deriv_iff_field_differentiable x_S at_within_open by force
    hence "(λh. (f (x+h) - f x) / h) 0 deriv f x" using DERIV_def by auto
    hence "d. (i. d i  UNIV-{0::real})  d  0 
      ((λh. (f (x+h) - f x) / h)  d)  deriv f x"
      using tendsto_at_iff_sequentially by blast
    moreover have "i. 1 / Suc i  UNIV - {0::real}" by simp
    moreover have "(λi. 1 / Suc i)  0" using LIMSEQ_Suc lim_const_over_n by blast
    ultimately have "((λh. (f (x+h) - f x) / h)  (λi. 1 / Suc i))  deriv f x" by auto
    thus "deriv f x = lim (λi. (f (x + 1 / Suc i) - f x) / (1 / Suc i))"
      unfolding comp_def by (simp add: limI)
  qed
  moreover have "(λx. indicator S x * lim (λi. (f (x + 1 / Suc i) - f x) / (1 / Suc i)))
     borel_measurable borel"
    using assms by (measurable, simp, measurable)
  ultimately show ?thesis
    unfolding set_borel_measurable_def real_scaleR_def
    by (smt (verit) indicator_simps measurable_cong mult_eq_0_iff)
qed

corollary deriv_measurable_real_UNIV:
  fixes f :: "real  real"
  assumes "f differentiable_on UNIV" "f  borel_measurable borel"
  shows "deriv f  borel_measurable borel"
  using deriv_measurable_real[where S=UNIV] assms by simp

lemma piecewise_differentiable_on_deriv_measurable_real:
  fixes f :: "real  real"
  assumes "f piecewise_differentiable_on S" "open S" "f  borel_measurable borel"
  shows "set_borel_measurable borel S (deriv f)"
proof -
  from assms obtain T where fin: "finite T" and
    diff: "x. x  S - T  f differentiable at x within S"
    unfolding piecewise_differentiable_on_def by blast
  with assms have "open (S - T)" using finite_imp_closed by blast
  moreover hence "f differentiable_on (S - T)"
    unfolding differentiable_on_def using assms by (metis Diff_iff at_within_open diff)
  ultimately have "set_borel_measurable borel (S - T) (deriv f)"
    by (intro deriv_measurable_real; simp add: assms)
  thus ?thesis
    unfolding set_borel_measurable_def real_scaleR_def
    by (rule measurable_discrete_difference[where X=T])
      (simp_all add: countable_finite fin indicator_diff)

qed

corollary piecewise_differentiable_on_deriv_measurable_real_UNIV:
  fixes f :: "real  real"
  assumes "f piecewise_differentiable_on UNIV" "f  borel_measurable borel"
  shows "(deriv f)  borel_measurable borel"
  using piecewise_differentiable_on_deriv_measurable_real[where S=UNIV] assms by simp

lemma einterval_empty:
  fixes a b :: ereal
  assumes "a  b"
  shows "einterval a b = {}"
  using assms einterval_iff by auto

lemma einterval_split:
  fixes a b :: ereal and s::real
  assumes "s  einterval a b"
  shows "einterval a b - {s} = einterval a s  einterval s b"
proof
  show "einterval a b - {s}  einterval a (ereal s)  einterval (ereal s) b"
    using assms einterval_iff by auto
  show "einterval a (ereal s)  einterval (ereal s) b  einterval a b - {s}"
    using assms einterval_iff
    by (smt (verit, ccfv_threshold) Diff_iff Diff_insert_absorb Un_iff
        order.strict_trans less_ereal.simps subsetI)
qed

(* analogue for lemma einterval_Icc_approximation *)
lemma einterval_Ioc_approximation:
  fixes a b :: ereal
  assumes "a < b"
  obtains u l :: "nat  real" where
    "einterval a b = (i. {l i <.. u i})"
    "incseq u" "decseq l" "i. l i < u i" "i. a < l i" "i. u i < b"
    "l  a" "u  b"
proof -
  from assms obtain u l :: "nat  real" where
    "einterval a b = (i. {l i .. u i})"
    "incseq u" "decseq l" "i. l i < u i" "i. a < ereal (l i)" "i. ereal (u i) < b"
    "(λi. ereal (l i))  a" "(λi. ereal (u i))  b"
    using einterval_Icc_approximation by (smt (verit) Sup.SUP_cong)
  moreover have "(i. {l i .. u i}) = (i. {l i <.. u i})"
  proof
    show "(i. {l i .. u i})  (i. {l i <.. u i})"
    proof
      fix x assume "x  (i. {l i .. u i})"
      from this obtain i where xi: "x  {l i .. u i}" by blast
      obtain j where "j  i" "l j < l i"
      proof (cases a = -)
        case True
        with (λi. ereal (l i))  a obtain k where "l k  ereal (l i - 1)"
          using Lim_MInfty by (meson nle_le)
        hence "l k < l i" by simp
        hence "l (max i k + 1) < l i"
          using decseq l by (smt (verit, del_insts) decseq_def le_add1 max.cobounded2)
        moreover have "max i k + 1  i" by simp
        ultimately show ?thesis using that by simp
      next
        case False
        with assms obtain ar where aar: "a = ereal ar" using less_ereal.simps by (metis ereal_cases)
        with (λi. ereal (l i))  a have "l  ar" by auto
        moreover have "0 < l i - ar" using i. a < ereal (l i) aar by simp
        ultimately obtain k where "h. h  k  norm (l h - ar) < l i - ar"
          using LIMSEQ_D by blast
        hence "h. h  k  l h < l i" by force
        hence "l (max i k + 1) < l i" by simp
        moreover have "max i k + 1  i" by simp
        ultimately show ?thesis using that by simp
      qed
      hence "x  {l j <.. u j}" using xi assms incseq u monoD by fastforce
      thus "x  (i. {l i <.. u i})" by blast
    qed
  next
    have "i. {l i <.. u i}  {l i .. u i}" by force
    thus "(i. {l i <.. u i})  (i. {l i .. u i})" by blast
  qed
  ultimately show ?thesis using that by simp
qed

(* Analogue for "measure_eqI_lessThan" in the "Lebesgue_Measure" Theory *)
lemma measure_eqI_Ioc:
  fixes M N :: "real measure"
  assumes sets: "sets M = sets borel" "sets N = sets borel"
  assumes fin: "a b. a  b  emeasure M {a<..b} < "
  assumes eq: "a b. a  b  emeasure M {a<..b} = emeasure N {a<..b}"
  shows "M = N"
proof (rule measure_eqI_generator_eq_countable)
  let ?Ioc = "λ(a::real,b::real). {a<..b}" let ?E = "range ?Ioc"
  show "Int_stable ?E" using Int_stable_def Int_greaterThanAtMost by force
  show "?E  Pow UNIV" "sets M = sigma_sets UNIV ?E" "sets N = sigma_sets UNIV ?E"
    unfolding sets by (auto simp add: borel_sigma_sets_Ioc)
  show "I. I  ?E  emeasure M I = emeasure N I"
  proof -
    fix I assume "I  ?E"
    then obtain a b where "I = {a<..b}" by auto
    thus "emeasure M I = emeasure N I" by (smt (verit, best) eq greaterThanAtMost_empty)
  qed
  show "?Ioc ` (Rats × Rats)  ?E" "(i(Rats×Rats). ?Ioc i) = UNIV"
    using Rats_no_bot_less Rats_no_top_le by auto
  show "countable (?Ioc ` (Rats × Rats))" using countable_rat by blast
  show "I. I  ?Ioc ` (Rats × Rats)  emeasure M I  "
  proof -
    fix I assume "I  ?Ioc ` (Rats × Rats)"
    then obtain a b where "(a,b)  (Rats × Rats)" "I = {a<..b}" by blast
    thus "emeasure M I  " by (smt (verit, best) Ioc_inj fin order.strict_implies_not_eq)
  qed
qed

lemma measure_einterval_eqI_Ioc:
  fixes M N :: "real measure" and a b :: ereal
  assumes Mborel: "sets M = sets borel" and Nborel: "sets N = sets borel" and
    "s t. a < ereal s  s  t  ereal t < b  emeasure M {s<..t}  " and
    "s t. a < ereal s  s  t  ereal t < b  emeasure M {s<..t} = emeasure N {s<..t}"
  shows "restrict_space M (einterval a b) = restrict_space N (einterval a b)"
proof (cases a < b)

  case ab: True

  let ?Iab = "einterval a b"
  let ?Iocs = "{{s<..t} | s t :: real. a < ereal s  s  t  ereal t < b}"

  have Iocs_Iab: "?Iocs  Pow ?Iab"
    by safe (metis einterval_iff greaterThanAtMost_iff ereal_less_le le_ereal_less less_eq_ereal_def)

  obtain u l :: "nat  real" where
    Iab_Un: "?Iab = (i. {l i <.. u i})" and
    lu: "i. l i < u i" and al: "i. a < l i" and ub: "i. u i < b"
  using einterval_Ioc_approximation ab by (smt (verit) Inf.INF_cong)

  let ?Iocn = "λn::nat. {l n <.. u n}"

  have Iabsigma: "L :: real measure. sets L = sets borel 
    sets (restrict_space L ?Iab) = sigma_sets ?Iab ?Iocs"
  proof -
    fix L :: "real measure" assume asm: "sets L = sets borel"
    have "sets (restrict_space L ?Iab) = (inter ?Iab) ` sigma_sets UNIV (range (λ(s,t)  {s<..t}))"
      by (rewrite sets_restrict_space, rewrite asm, rewrite borel_sigma_sets_Ioc) simp
    also have " = sigma_sets ?Iab ((inter ?Iab) ` {{s<..t} | s t. True})"
      apply (rewrite restricted_sigma)
        apply (metis Pow_UNIV borel_einterval borel_sigma_sets_Ioc sets_measure_of top_greatest)
      unfolding image_def by simp_all
    also have " = sigma_sets ?Iab ?Iocs"
    proof
      have "(inter ?Iab) ` {{s<..t} | s t. True}  sigma_sets ?Iab ?Iocs"
      proof
        fix A assume "A  (inter ?Iab) ` {{s<..t} | s t. True}"
        from this obtain s t where Aabst: "A = ?Iab  {s<..t}" by blast
        also have " = (n. {l n <.. u n}  {s<..t})" using Aabst Iab_Un UN_simps by force
        also have " = (n. {max (l n) s <.. min (u n) t})" by simp
        moreover have
          "n. {max (l n) s <.. min (u n) t}  sigma_sets ?Iab ?Iocs"
        proof -
          fix n
          show "{max (l n) s <.. min (u n) t}  sigma_sets ?Iab ?Iocs"
          proof (cases max (l n) s  min (u n) t)
            case True
            moreover have "a < ereal (max (l n) s)" using al by (metis less_ereal_le max_def)
            moreover have "ereal (min (u n) t) < b" using ub by (smt (verit) ereal_less_le)
            ultimately have "{max (l n) s <.. min (u n) t}  ?Iocs" by blast
            thus ?thesis ..
          next
            case False
            hence "{max (l n) s <.. min (u n) t} = {}" by auto
            thus ?thesis by (metis sigma_sets.Empty)
          qed
        qed
        ultimately show "A  sigma_sets ?Iab ?Iocs" by (simp add: sigma_sets.Union)
      qed
      thus "sigma_sets ?Iab ((inter ?Iab) ` {{s<..t} | s t. True})  sigma_sets ?Iab ?Iocs"
        by (rule sigma_sets_mono)
    next
      have "?Iocs  sigma_sets ?Iab ((inter ?Iab) ` {{s<..t} | s t. True})"
      proof
        fix A assume "A  ?Iocs"
        from this obtain s t where "a < ereal s  s  t  ereal t < b" and "A = {s<..t}" by blast
        hence "A = ?Iab  {s<..t}" using Iocs_Iab by blast
        hence "A  (inter ?Iab) ` {{s<..t} | s t. True}" by auto
        thus "A  sigma_sets ?Iab ((inter ?Iab) ` {{s<..t} | s t. True})" by blast
      qed
      thus "sigma_sets ?Iab ?Iocs  sigma_sets ?Iab ((inter ?Iab) ` {{s<..t} | s t. True})"
        by (rule sigma_sets_mono)
    qed
    finally show "sets (restrict_space L ?Iab) = sigma_sets ?Iab ?Iocs" .
  qed

  have "Int_stable ?Iocs"
  proof (rule Int_stableI)
    fix A B assume "A  ?Iocs" "B  ?Iocs"
    from this obtain sA tA sB tB where
      asA: "a < ereal sA" and sAtA: "sA  tA" and tAb: "ereal tA < b" and "A = {sA <.. tA}" and
      asB: "a < ereal sB" and sBtB: "sB  tB" and eBb: "ereal tB < b" and "B = {sB <.. tB}"
      by blast
    hence AB: "A  B = {max sA sB <.. min tA tB}" using Int_greaterThanAtMost by blast
    thus "A  B  ?Iocs"
    proof (cases max sA sB  min tA tB)
      case True
      moreover have "a < ereal (max sA sB)" "ereal (min tA tB) < b"
        using asA tAb asB eBb by linarith+
      ultimately show ?thesis using AB by blast
    next
      case False
      hence "A  B = {}" using AB by force
      thus "A  B  ?Iocs" using asA less_ereal_le sAtA tAb by fastforce
    qed
  qed
  moreover note Iocs_Iab
  moreover have "A. A  ?Iocs 
    emeasure (restrict_space M ?Iab) A = emeasure (restrict_space N ?Iab) A"
  proof -
    fix A assume asm: "A  ?Iocs"
    hence [simp]: "A  ?Iab" using Iocs_Iab by blast
    have "emeasure (restrict_space M ?Iab) A = emeasure M A"
      by (rewrite emeasure_restrict_space; simp add: assms)
    also have " = emeasure N A" using assms asm by force
    also have " = emeasure (restrict_space N ?Iab) A"
      by (rewrite emeasure_restrict_space; simp add: assms)
    finally show "emeasure (restrict_space M ?Iab) A = emeasure (restrict_space N ?Iab) A" .
  qed
  moreover have "sets (restrict_space M ?Iab) = sigma_sets ?Iab ?Iocs" using Iabsigma assms by simp
  moreover have "sets (restrict_space N ?Iab) = sigma_sets ?Iab ?Iocs" using Iabsigma assms by simp
  moreover have rngIocn: "range ?Iocn  ?Iocs"
    using al lu ub by (smt (verit) image_subset_iff mem_Collect_eq)
  moreover have "(n. ?Iocn n) = ?Iab" using Iab_Un by simp
  moreover have "n. emeasure (restrict_space M ?Iab) (?Iocn n)  "
  proof -
    fix n::nat
    have "{l n <.. u n}  ?Iab" using Iab_Un by blast
    moreover have "emeasure M {l n <.. u n}  " using assms al lu ub less_imp_le by metis
    ultimately show "emeasure (restrict_space M ?Iab) (?Iocn n)  "
      by (rewrite emeasure_restrict_space; simp add: assms)
  qed
  ultimately show "restrict_space M ?Iab = restrict_space N ?Iab"
    by (rule measure_eqI_generator_eq[where A="?Iocn"]; simp)

next

  case False
  hence "einterval a b = {}" using einterval_empty by simp
  thus ?thesis by (metis sets.empty_sets space_empty_eq_bot space_restrict_space2)

qed

lemma nn_integral_disjoint_pair2:
  assumes "B  sets M" "C  sets M" "B  C = {}" and
    [measurable]: "(λx. f x * indicator B x)  borel_measurable M" and
    [measurable]: "(λx. f x * indicator C x)  borel_measurable M"
  shows "(+x  B  C. f x M) = (+x  B. f x M) + (+x  C. f x M)"
proof -
  have [measurable]: "(λx. f x * indicator (B  C) x)  borel_measurable M"
    using assms apply (rewrite indicator_add[THEN sym], simp)
    apply (rewrite distrib_left) by simp
  have "(+x  B  C. f x M) = (+x  B  C. f x * indicator (B  C) x M)"
    by (metis indicator_simps mult_1_right mult_eq_0_iff)
  also have " = (+xB. f x * indicator (B  C) x M) + (+xC. f x * indicator (B  C) x M)"
    using assms by (rewrite nn_integral_disjoint_pair; simp)
  moreover have "(+xB. f x * indicator (B  C) x M) = (+xB. f x M)"
    by (metis (mono_tags, lifting) indicator_inter_arith inf_sup_absorb mult.assoc mult.commute)
  moreover have "(+xC. f x * indicator (B  C) x M) = (+xC. f x M)"
    by (metis (no_types, lifting) indicator_inter_arith inf_sup_absorb mult.commute
        mult.left_commute sup_commute)
  ultimately show ?thesis by simp
qed

lemma set_nn_integral_interval_measure_bounded_finite:
  fixes F :: "real  real" and h :: "real  ennreal" and A :: "real set" and M::real
  assumes "bounded A" "x. x  A  h x  M" "A  sets borel" and
    "mono F" "x. continuous (at_right x) F"
  shows "(+xA. h x (interval_measure F)) < "
proof -
  let ?IMF = "interval_measure F"
  obtain a where a_ub: "x. x  A  ¦x¦  a"
    using bounded_iff assms by force
  define c where "c  ¦a¦ + 1"
  have [simp]: "c > 0"
    unfolding c_def by auto
  have Ac: "A  {-c<..c}"
    using a_ub c_def by force
  have "(+xA. h x ?IMF)  (+xA. M ?IMF)"
    using nn_set_integral_mono assms by (simp add: indicator_def nn_integral_mono)
  also have "  (+x{-c<..c}. M ?IMF)"
    using nn_set_integral_set_mono Ac by force
  also have " = M * emeasure ?IMF {-c<..c}"
    by (rewrite nn_integral_cmult_indicator; simp)
  also have "  ¦M¦ * emeasure ?IMF {-c<..c}"
    using abs_ge_self by (simp add: mult_right_mono)
  also have "emeasure ?IMF {-c<..c} = F c - F (-c)"
    by (simp add: emeasure_interval_measure_Ioc_eq ennreal_eq_0_iff monoD assms)
  finally have "(+xA. h x ?IMF)  ¦M¦ * (F c - F (-c))"
    by (simp add: ennreal_mult')
  then show ?thesis
    by (simp add: le_less_trans)
qed

end