Theory Miscellaneous_Lemmas

section‹Miscellaneous technical lemmas›

(*
  Title:   Miscellaneous_Lemmas.thy
  Authors: Angeliki Koutsoukou-Argyraki, Mantas Bakšys, and Chelsea Edmonds
  Affiliation: University of Cambridge
  Date: August 2022.
*)

theory Miscellaneous_Lemmas
  imports 
    "HOL-Library.Indicator_Function"
    "HOL-Analysis.Convex"
begin

lemma set_pairs_filter_subset: "A  B  {p . p  A × A  P p}  {p. p  B × B  P p}"
  by (intro subsetI) blast

lemma card_set_ss_indicator: 
  assumes "A  B"
  assumes "finite B"
  shows "card A = ( p  B. indicator A p)"
proof -
  obtain C where ceq: "C = B - A" by blast
  then have beq: "B = A  C" using assms by blast
  have bint: "A  C = {}" using ceq by blast
  have finite: "finite A" using assms finite_subset by auto 
  have zero: " p. p  C  indicator (A) p = 0"
    by (simp add: ceq) 
  then have "card A = ( p  A . indicator (A) p)"
    by simp 
  also have "... = ( p  A . indicator A p) + ( p  C . indicator A p)" 
    using zero by (metis add_cancel_left_right sum.neutral) 
  finally show "card A = ( p  B. indicator A p)" using beq bint assms
    by (metis add.commute ceq sum.subset_diff) 
qed

lemma card_cartesian_prod_square: "finite X  card (X × X) = (card X)^2" 
  using card_cartesian_product by (simp add: power2_eq_square) 

lemma (in ordered_ab_group_add) diff_strict1_mono: 
  assumes "a > a'" "b  b'"
  shows "a - b > a' - b'"
  using diff_strict_mono assms
  by (metis local.diff_strict_right_mono local.dual_order.not_eq_order_implies_strict) 

lemma card_cartesian_product_6: "card (A × A × A × A × A × A) = (card A) ^ 6"
proof-
  have "card (A × A × A × A × A × A) = 
    card A * card A * card A * card A * card A * card A" 
    using card_cartesian_product mult.commute by metis
  then show ?thesis by algebra
qed

lemma card_cartesian_product3: "card (X × Y × Z) = card X * card Y * card Z"
  using card_cartesian_product  by (metis mult.commute mult.left_commute)  


lemma card_le_image_div:
  fixes A:: "'a set" and B:: "'b set" and f:: "'a  'b set" and r:: real
  assumes "finite B" and "pairwise (λ s t. disjnt (f s) (f t)) A" and " d  A. (card (f d))  r" 
  and " d  A. f d  B" and "r > 0"
  shows "card A  card B / r"

proof (cases "finite A")
  assume hA: "finite A"
  have hpair_disj: "pairwise disjnt (f ` A)" using assms by (metis pairwiseD pairwise_imageI)
  have "r * card A = ( d  A. r)" by simp
  also have "...  ( d  A. card (f d))" using assms sum_mono by fastforce
  also have "... = sum card (f ` A)" using assms hA by (simp add: sum_card_image)
  also have "... = card ( d  A. f d)" using assms hA hpair_disj
    by (metis Sup_upper card_Union_disjoint finite_UN_I rev_finite_subset)
  also have "...  card B" using assms card_mono
    by (metis UN_subset_iff of_nat_le_iff)
  finally have "r * card A  card B" by linarith
  thus ?thesis using divide_le_eq assms by (simp add: mult_imp_le_div_pos mult_of_nat_commute)
next
  assume "¬ finite A"
  thus ?thesis using assms by auto
qed

lemma list_middle_eq: 
  "length xs = length ys  hd xs = hd ys  last xs = last ys 
     butlast (tl xs) = butlast (tl ys)  xs = ys"
  apply (induct xs ys rule: list_induct2, simp)
  by (metis append_butlast_last_id butlast.simps(1) butlast.simps(2) butlast_tl hd_Cons_tl 
      impossible_Cons le_refl list.sel(3) neq_Nil_conv)

lemma list2_middle_singleton: 
  assumes "length xs = 3"
  shows "butlast (tl xs) = [xs ! 1]"
proof (simp add: list_eq_iff_nth_eq assms)
  have l: "length (butlast (tl xs)) = 1" using length_butlast length_tl assms by simp 
  then have " butlast (tl xs) ! 0 = (tl xs) ! 0" using nth_butlast[of 0 "tl xs"] by simp
  then show "butlast (tl xs) ! 0 = xs ! Suc 0" using nth_tl[of 0 xs]  l by simp
qed


lemma le_powr_half_mult:
  fixes x y z:: real
  assumes "x ^ 2  y * z" and "0  y" and "0  z"
  shows "x  y powr(1/2) * z powr (1/2)"
  using assms power2_eq_square
  by (metis dual_order.trans linorder_linear powr_ge_zero powr_half_sqrt powr_mult real_le_rsqrt 
    real_sqrt_le_0_iff)

lemma Cauchy_Schwarz_ineq_sum2:
  fixes f g:: "'a  real" and A:: "'a set"
  shows "( d  A. f d * g d)  
    ( d  A. (f d)^2) powr (1/2) * ( d  A. (g d)^2) powr (1/2)"
  using Convex.Cauchy_Schwarz_ineq_sum[of "f" "g" "A"] le_powr_half_mult sum_nonneg zero_le_power2
  by (metis (mono_tags, lifting))

end