Theory CRR_Model

(*  Title:      CRR_Model.thy
    Author:     Mnacho Echenim, Univ. Grenoble Alpes
*)

section ‹The Cox Ross Rubinstein model›

text ‹This section defines the Cox-Ross-Rubinstein model of a financial market, and charcterizes a risk-neutral
probability space for this market. This, together with the proof that every derivative is attainable, permits to
obtain a formula to explicitely compute the fair price of any derivative.›

theory CRR_Model imports Fair_Price

begin

locale CRR_hyps = prob_grw + rsk_free_asset +
  fixes stk
assumes stocks: "stocks Mkt = {stk, risk_free_asset}"
  and stk_price: "prices Mkt stk = geom_proc"
  and S0_positive: "0 < init"
  and down_positive: "0 < d" and down_lt_up: "d < u"
  and psgt: "0 < p"
  and pslt: "p < 1"


locale CRR_market = CRR_hyps +
  fixes G
assumes stock_filtration:"G = stoch_proc_filt M geom_proc borel"

subsection ‹Preliminary results on the market›

lemma (in CRR_market) case_asset:
  assumes "asset  stocks Mkt"
  shows "asset = stk  asset = risk_free_asset"
proof (rule ccontr)
  assume "¬ (asset = stk  asset = risk_free_asset)"
  hence "asset  stk  asset  risk_free_asset" by simp
  moreover have "asset  {stk, risk_free_asset}" using assms stocks by simp
  ultimately show False by auto
qed

lemma (in CRR_market)
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows bernoulli_gen_filtration: "filtration N G"
and bernoulli_sigma_finite: "n. sigma_finite_subalgebra N (G n)"
proof -
  show "filtration N G"
  proof -
    have "disc_filtr M (stoch_proc_filt M geom_proc borel)"
    proof (rule stoch_proc_filt_disc_filtr)
      fix i
      show "random_variable borel (geom_proc i)"
        by (simp add: geom_rand_walk_borel_measurable)
    qed
    hence "filtration M G" using stock_filtration  by (simp add: filtration_def disc_filtr_def)
    have "filt_equiv nat_filtration M N" using pslt psgt by (simp add: assms bernoulli_stream_equiv)
    hence "sets N = sets M" unfolding filt_equiv_def by simp
    thus ?thesis unfolding filtration_def
      by (metis filtration_def Filtration.filtration M G sets_eq_imp_space_eq subalgebra_def)
  qed
  show "n. sigma_finite_subalgebra N (G n)" using assms unfolding subalgebra_def
    using  filtration_def  subalgebra_sigma_finite
    by (metis Filtration.filtration N G bernoulli_stream_def prob_space.prob_space_stream_space
        prob_space.subalgebra_sigma_finite prob_space_measure_pmf)
qed


sublocale CRR_market  rfr_disc_equity_market  _ G
proof (unfold_locales)
  show  "disc_filtr M G  sets (G ) = {{}, space M}"
  proof
    show "sets (G ) = {{}, space M}" using infinite_cts_filtration.stoch_proc_filt_triv_init stock_filtration geometric_process
        geom_rand_walk_borel_adapted
      by (meson infinite_coin_toss_space_axioms infinite_cts_filtration_axioms.intro infinite_cts_filtration_def
          init_triv_filt_def)
    show "disc_filtr M G"
      by (metis Filtration.filtration_def bernoulli bernoulli_gen_filtration disc_filtr_def psgt pslt)
  qed
  show "assetstocks Mkt. borel_adapt_stoch_proc G (prices Mkt asset)"
  proof -
    have "borel_adapt_stoch_proc G (prices Mkt stk)" using stk_price stock_filtration stoch_proc_filt_adapt
      by (simp add: stoch_proc_filt_adapt geom_rand_walk_borel_measurable)
    moreover have "borel_adapt_stoch_proc G (prices Mkt risk_free_asset)"
      using disc_filtr M G  sets (G ) = {{}, space M} disc_filtr_prob_space.disc_rfr_proc_borel_adapted
        disc_filtr_prob_space.intro disc_filtr_prob_space_axioms.intro prob_space_axioms rf_price by fastforce
    moreover have "disc_filtr_prob_space M G" proof (unfold_locales)
      show "disc_filtr M G" by (simp add: disc_filtr M G  sets (G ) = {{}, space M})
    qed
    ultimately show ?thesis using stocks by force
  qed
qed




lemma (in CRR_market) two_stocks:
shows "stk  risk_free_asset"
proof (rule ccontr)
  assume "¬stk  risk_free_asset"
  hence "disc_rfr_proc r = prices Mkt stk" using rf_price by simp
  also have "... = geom_proc" using stk_price by simp
  finally have eqf: "disc_rfr_proc r = geom_proc" .
  hence "w. disc_rfr_proc r 0 w = geom_proc 0 w" by simp
  hence "1 = init" using geometric_process by simp
  have eqfs: "w. disc_rfr_proc r (Suc 0) w = geom_proc (Suc 0) w" using eqf by simp
  hence "disc_rfr_proc r (Suc 0) (sconst True) = geom_proc (Suc 0) (sconst True)" by simp
  hence "1+r = u" using geometric_process 1 = init by simp
  have "disc_rfr_proc r (Suc 0) (sconst False) = geom_proc (Suc 0) (sconst False)" using eqfs by simp
  hence "1+r = d" using geometric_process 1 = init by simp
  show False using 1+r = u 1+r = d down_lt_up by simp
qed


lemma (in CRR_market) stock_pf_vp_expand:
  assumes "stock_portfolio Mkt pf"
  shows "val_process Mkt pf n w = geom_proc n w * pf stk (Suc n) w +
    disc_rfr_proc r n w * pf risk_free_asset (Suc n) w"
proof -
  have "val_process Mkt pf n w =(sum (λx. ((prices Mkt) x n w) * (pf x (Suc n) w)) (stocks Mkt))"
  proof (rule subset_val_process')
    show "finite (stocks Mkt)" using stocks by auto
    show "support_set pf  stocks Mkt" using assms unfolding stock_portfolio_def by simp
  qed
  also have "... = (x {stk, risk_free_asset}. ((prices Mkt) x n w) * (pf x (Suc n) w))" using stocks  by simp
  also have "... =  prices Mkt stk n w * pf stk (Suc n) w +
    ( x {risk_free_asset}. ((prices Mkt) x n w) * (pf x (Suc n) w))" by (simp add:two_stocks)
  also have "... = prices Mkt stk n w * pf stk (Suc n) w +
    prices Mkt risk_free_asset n w * pf risk_free_asset (Suc n) w" by simp
  also have "... = geom_proc n w * pf stk (Suc n) w + disc_rfr_proc r n w * pf risk_free_asset (Suc n) w"
    using rf_price stk_price by simp
  finally show ?thesis .
qed

lemma (in CRR_market) stock_pf_uvp_expand:
  assumes "stock_portfolio Mkt pf"
  shows "cls_val_process Mkt pf (Suc n) w = geom_proc (Suc n) w * pf stk (Suc n) w +
    disc_rfr_proc r (Suc n) w * pf risk_free_asset (Suc n) w"
proof -
  have "cls_val_process Mkt pf (Suc n) w =(sum (λx. ((prices Mkt) x (Suc n) w) * (pf x (Suc n) w)) (stocks Mkt))"
  proof (rule subset_cls_val_process')
    show "finite (stocks Mkt)" using stocks by auto
    show "support_set pf  stocks Mkt" using assms unfolding stock_portfolio_def by simp
  qed
  also have "... = (x {stk, risk_free_asset}. ((prices Mkt) x (Suc n) w) * (pf x (Suc n) w))" using  stocks by simp
  also have "... =  prices Mkt stk (Suc n) w * pf stk (Suc n) w +
    ( x {risk_free_asset}. ((prices Mkt) x (Suc n) w) * (pf x (Suc n) w))" by (simp add:two_stocks)
  also have "... = prices Mkt stk (Suc n) w * pf stk (Suc n) w +
    prices Mkt risk_free_asset (Suc n) w * pf risk_free_asset (Suc n) w" by simp
  also have "... = geom_proc (Suc n) w * pf stk (Suc n) w + disc_rfr_proc r (Suc n) w * pf risk_free_asset (Suc n) w"
    using rf_price stk_price by simp
  finally show ?thesis .
qed



lemma (in CRR_market) pos_pf_neg_uvp:
  assumes "stock_portfolio Mkt pf"
  and "d < 1+r"
  and "0 < pf stk (Suc n) (spick w n False)"
  and "val_process Mkt pf n (spick w n False)  0"
shows "cls_val_process Mkt pf (Suc n) (spick w n False) < 0"
proof -
  define wnf where "wnf = spick w n False"
  have "cls_val_process Mkt pf (Suc n) (spick w n False) =
    geom_proc (Suc n) wnf * pf stk (Suc n) wnf +
    disc_rfr_proc r (Suc n) wnf * pf risk_free_asset (Suc n) wnf" unfolding wnf_def
    using assms by (simp add:stock_pf_uvp_expand)
  also have "... = d * geom_proc n wnf * pf stk (Suc n) wnf + disc_rfr_proc r (Suc n) wnf * pf risk_free_asset (Suc n) wnf"
    unfolding wnf_def using geometric_process spickI[of n w False] by simp
  also have "... = d * geom_proc n wnf * pf stk (Suc n) wnf + (1+r) * disc_rfr_proc r n wnf * pf risk_free_asset (Suc n) wnf"
    by simp
  also have "... < (1+r) * geom_proc n wnf * pf stk (Suc n) wnf + (1+r) * disc_rfr_proc r n wnf * pf risk_free_asset (Suc n) wnf"
    unfolding wnf_def using assms geom_rand_walk_strictly_positive S0_positive
      down_positive down_lt_up by simp
  also have "... = (1+r) * (geom_proc n wnf * pf stk (Suc n) wnf + disc_rfr_proc r n wnf * pf risk_free_asset (Suc n) wnf)"
    by (simp add: distrib_left)
  also have "... = (1+r) * val_process Mkt pf n wnf" using stock_pf_vp_expand assms by simp
  also have "...  0"
  proof -
    have "0 < 1+r" using assms down_positive by simp
    moreover have "val_process Mkt pf n wnf  0" using assms unfolding wnf_def by simp
    ultimately show "(1+r) * (val_process Mkt pf n wnf)   0" unfolding wnf_def
      using less_eq_real_def[of 0 "1+r"] mult_nonneg_nonpos[of "1+r" "val_process Mkt pf n (spick w n False)"] by simp
  qed
  finally show ?thesis .
qed


lemma (in CRR_market) neg_pf_neg_uvp:
  assumes "stock_portfolio Mkt pf"
  and "1+r < u"
  and "pf stk (Suc n) (spick w n True) < 0"
  and "val_process Mkt pf n (spick w n True)  0"
shows "cls_val_process Mkt pf (Suc n) (spick w n True) < 0"
proof -
  define wnf where "wnf = spick w n True"
  have "cls_val_process Mkt pf (Suc n) (spick w n True) =
    geom_proc (Suc n) wnf * pf stk (Suc n) wnf +
    disc_rfr_proc r (Suc n) wnf * pf risk_free_asset (Suc n) wnf" unfolding wnf_def
    using assms by (simp add:stock_pf_uvp_expand)
  also have "... = u * geom_proc n wnf * pf stk (Suc n) wnf + disc_rfr_proc r (Suc n) wnf * pf risk_free_asset (Suc n) wnf"
    unfolding wnf_def using geometric_process spickI[of n w True] by simp
  also have "... = u * geom_proc n wnf * pf stk (Suc n) wnf + (1+r) * disc_rfr_proc r n wnf * pf risk_free_asset (Suc n) wnf"
    by simp
  also have "... < (1+r) * geom_proc n wnf * pf stk (Suc n) wnf + (1+r) * disc_rfr_proc r n wnf * pf risk_free_asset (Suc n) wnf"
    unfolding wnf_def using assms geom_rand_walk_strictly_positive S0_positive
      down_positive down_lt_up by simp
  also have "... = (1+r) * (geom_proc n wnf * pf stk (Suc n) wnf + disc_rfr_proc r n wnf * pf risk_free_asset (Suc n) wnf)"
    by (simp add: distrib_left)
  also have "... = (1+r) * val_process Mkt pf n wnf" using stock_pf_vp_expand assms by simp
  also have "...  0"
  proof -
    have "0 < 1+r" using acceptable_rate by simp
    moreover have "val_process Mkt pf n wnf  0" using assms unfolding wnf_def by simp
    ultimately show "(1+r) * (val_process Mkt pf n wnf)   0" unfolding wnf_def
      using less_eq_real_def[of 0 "1+r"] mult_nonneg_nonpos[of "1+r" "val_process Mkt pf n (spick w n True)"] by simp
  qed
  finally show ?thesis .
qed




lemma (in CRR_market) zero_pf_neg_uvp:
  assumes "stock_portfolio Mkt pf"
  and "pf stk (Suc n) w = 0"
  and "pf risk_free_asset (Suc n) w  0"
  and "val_process Mkt pf n w  0"
shows "cls_val_process Mkt pf (Suc n) w < 0"
proof -
  have "cls_val_process Mkt pf (Suc n) w =
    S (Suc n) w * pf stk (Suc n) w +
    disc_rfr_proc r (Suc n) w * pf risk_free_asset (Suc n) w"
    using assms by (simp add:stock_pf_uvp_expand)
  also have "... = disc_rfr_proc r (Suc n) w * pf risk_free_asset (Suc n) w" using assms by simp
  also have "... = (1+r) * disc_rfr_proc r n w * pf risk_free_asset (Suc n) w" by simp
  also have "... < 0"
  proof -
    have "0 < 1+r" using acceptable_rate by simp
    moreover have "0 < disc_rfr_proc r n w" using acceptable_rate by (simp add: disc_rfr_proc_positive)
    ultimately have "0 < (1+r) * disc_rfr_proc r n w" by simp
    have 1: "0< pf risk_free_asset (Suc n) w  0 <(1+r) * disc_rfr_proc r n w * pf risk_free_asset (Suc n) w"
    proof (intro impI)
      assume "0 < pf risk_free_asset (Suc n) w"
      thus "0 < (1 + r) * disc_rfr_proc r n w * pf risk_free_asset (Suc n) w" using 0 < (1+r) * disc_rfr_proc r n w
        by simp
    qed
    have 2: "pf risk_free_asset (Suc n) w < 0  (1+r) * disc_rfr_proc r n w * pf risk_free_asset (Suc n) w < 0"
    proof (intro impI)
      assume "pf risk_free_asset (Suc n) w < 0"
      thus "(1 + r) * disc_rfr_proc r n w * pf risk_free_asset (Suc n) w < 0" using 0 < (1+r) * disc_rfr_proc r n w
        by (simp add:mult_pos_neg)
    qed
    have "0  val_process Mkt pf n w" using assms by simp
    also have "val_process Mkt pf n w = geom_proc n w * pf stk (Suc n) w +
      disc_rfr_proc r n w * pf risk_free_asset (Suc n) w" using assms by (simp add:stock_pf_vp_expand)
    also have "... = disc_rfr_proc r n w * pf risk_free_asset (Suc n) w" using assms by simp
    finally have "0 disc_rfr_proc r n w * pf risk_free_asset (Suc n) w" .
    have "0< pf risk_free_asset (Suc n) w  pf risk_free_asset (Suc n) w < 0"  using assms
       by linarith
    thus ?thesis
      using "2" 0 < disc_rfr_proc r n w disc_rfr_proc r n w * pf risk_free_asset (Suc n) w  0
        mult_pos_pos by fastforce
  qed
  finally show ?thesis .
qed



lemma (in CRR_market) neg_pf_exists:
  assumes "stock_portfolio Mkt pf"
  and "trading_strategy pf"
  and "1+r < u"
  and "d < 1+r"
  and "val_process Mkt pf n w  0"
  and "pf stk (Suc n) w  0  pf risk_free_asset (Suc n) w  0"
shows "y. cls_val_process Mkt pf (Suc n) y < 0"
proof -
  have "borel_predict_stoch_proc G (pf stk)"
  proof (rule inc_predict_support_trading_strat')
    show "trading_strategy pf" using assms by simp
    show "stk  support_set pf  {stk}" by simp
  qed
  hence "pf stk (Suc n)  borel_measurable (G n)" unfolding predict_stoch_proc_def by simp
  have "val_process Mkt pf n  borel_measurable (G n)"
  proof -
    have "borel_adapt_stoch_proc G (val_process Mkt pf)" using assms
      using support_adapt_def ats_val_process_adapted readable unfolding  stock_portfolio_def by blast
    thus ?thesis unfolding adapt_stoch_proc_def by simp
  qed
  define wn where "wn = pseudo_proj_True n w"
  show ?thesis
  proof (cases "pf stk (Suc n) w  0")
    case True
    show ?thesis
    proof (cases "pf stk (Suc n) w > 0")
      case True
      have "0 <pf stk (Suc n) (spick wn n False)"
      proof -
        have "0 < pf stk (Suc n) w" using 0 < pf stk (Suc n) w by simp
        also have "... = pf stk (Suc n) wn" unfolding wn_def
          using pf stk (Suc n)  borel_measurable (G n) stoch_proc_subalg_nat_filt[of geom_proc] geometric_process
          nat_filtration_info stock_filtration
          by (metis comp_apply geom_rand_walk_borel_adapted measurable_from_subalg)
        also have "... = pf stk (Suc n) (spick wn n False)" using pf stk (Suc n)  borel_measurable (G n) comp_def nat_filtration_info
              pseudo_proj_True_stake_image spickI stoch_proc_subalg_nat_filt[of geom_proc] geometric_process stock_filtration
          by (metis geom_rand_walk_borel_adapted measurable_from_subalg)
        finally show ?thesis .
      qed
      moreover have "0  val_process Mkt pf n (spick wn n False)"
      proof -
        have "0  val_process Mkt pf n w" using assms by simp
        also have "val_process Mkt pf n w = val_process Mkt pf n wn" unfolding wn_def using val_process Mkt pf n  borel_measurable (G n)
          nat_filtration_info stoch_proc_subalg_nat_filt[of geom_proc] geometric_process
          stock_filtration by (metis comp_apply geom_rand_walk_borel_adapted measurable_from_subalg)
        also have "... = val_process Mkt pf n (spick wn n False)" using val_process Mkt pf n  borel_measurable (G n)
          comp_def nat_filtration_info
              pseudo_proj_True_stake_image spickI stoch_proc_subalg_nat_filt[of geom_proc] geometric_process stock_filtration
          by (metis geom_rand_walk_borel_adapted measurable_from_subalg)
        finally show ?thesis .
      qed
      ultimately have "cls_val_process Mkt pf (Suc n) (spick wn n False) < 0" using assms
        by (simp add:pos_pf_neg_uvp)
      thus "y. cls_val_process Mkt pf (Suc n) y < 0" by auto
    next
      case False
      have "0 >pf stk (Suc n) (spick wn n True)"
      proof -
        have "0 > pf stk (Suc n) w" using ¬ 0 < pf stk (Suc n) w pf stk (Suc n) w  0 by simp
        also have "pf stk (Suc n) w = pf stk (Suc n) wn" unfolding wn_def using pf stk (Suc n)  borel_measurable (G n)
          nat_filtration_info stoch_proc_subalg_nat_filt[of geom_proc] geometric_process
          stock_filtration by (metis comp_apply geom_rand_walk_borel_adapted measurable_from_subalg)
        also have "... = pf stk (Suc n) (spick wn n True)" using pf stk (Suc n)  borel_measurable (G n)
          comp_def nat_filtration_info
              pseudo_proj_True_stake_image spickI stoch_proc_subalg_nat_filt[of geom_proc] geometric_process stock_filtration
          by (metis geom_rand_walk_borel_adapted measurable_from_subalg)
        finally show ?thesis .
      qed
      moreover have "0  val_process Mkt pf n (spick wn n True)"
      proof -
        have "0  val_process Mkt pf n w" using assms by simp
        also have "val_process Mkt pf n w = val_process Mkt pf n wn" unfolding wn_def using val_process Mkt pf n  borel_measurable (G n)
          comp_def nat_filtration_info
              pseudo_proj_True_stake_image spickI stoch_proc_subalg_nat_filt[of geom_proc] geometric_process stock_filtration
          by (metis geom_rand_walk_borel_adapted measurable_from_subalg)
        also have "... = val_process Mkt pf n (spick wn n True)" using val_process Mkt pf n  borel_measurable (G n)
          comp_def nat_filtration_info
              pseudo_proj_True_stake_image spickI stoch_proc_subalg_nat_filt[of geom_proc] geometric_process stock_filtration
          by (metis geom_rand_walk_borel_adapted measurable_from_subalg)
        finally show ?thesis .
      qed
      ultimately have "cls_val_process Mkt pf (Suc n) (spick wn n True) < 0" using assms
        by (simp add:neg_pf_neg_uvp)
      thus "y. cls_val_process Mkt pf (Suc n) y < 0" by auto
    qed
  next
    case False
    hence "pf risk_free_asset (Suc n) w  0" using assms by simp
    hence "cls_val_process Mkt pf (Suc n) w < 0" using False assms by (auto simp add:zero_pf_neg_uvp)
    thus "y. cls_val_process Mkt pf (Suc n) y < 0" by auto
  qed
qed


lemma (in CRR_market) non_zero_components:
assumes "val_process Mkt pf n y  0"
and "stock_portfolio Mkt pf"
shows  "pf stk (Suc n) y  0  pf risk_free_asset (Suc n) y  0"
proof (rule ccontr)
  assume "¬(pf stk (Suc n) y  0  pf risk_free_asset (Suc n) y  0)"
  hence "pf stk (Suc n) y = 0" "pf risk_free_asset (Suc n) y = 0" by auto
  have "val_process Mkt pf n y = geom_proc n y * pf stk (Suc n) y +
    disc_rfr_proc r n y * pf risk_free_asset (Suc n) y" using stock_portfolio Mkt pf
    stock_pf_vp_expand[of pf n]  by simp
  also have "... = 0" using pf stk (Suc n) y = 0 pf risk_free_asset (Suc n) y = 0 by simp
  finally have "val_process Mkt pf n y = 0" .
  moreover have "val_process Mkt pf n y  0" using assms by simp
  ultimately show False by simp
qed

lemma (in CRR_market) neg_pf_Suc:
  assumes "stock_portfolio Mkt pf"
  and "trading_strategy pf"
  and "self_financing Mkt pf"
  and "1+r < u"
  and "d < 1+r"
  and "cls_val_process Mkt pf n w < 0"
shows "n  m  y. cls_val_process Mkt pf m y < 0"
proof (induct m)
  case 0
  assume "n  0"
  hence "n=0" by simp
  thus "y. cls_val_process Mkt pf 0 y < 0" using assms by auto
next
  case (Suc m)
  assume "n  Suc m"
  thus "y. cls_val_process Mkt pf (Suc m) y < 0"
  proof (cases "n < Suc m")
    case False
    hence "n = Suc m" using n  Suc m by simp
    thus "y. cls_val_process Mkt pf (Suc m) y < 0" using assms by auto
  next
    case True
    hence "n  m" by simp
    hence "y. cls_val_process Mkt pf m y < 0" using Suc by simp
    from this obtain y where "cls_val_process Mkt pf m y < 0" by auto
    hence "val_process Mkt pf m y < 0" using assms by (simp add:self_financingE)
    hence "val_process Mkt pf m y  0" by simp
    have "val_process Mkt pf m y  0" using val_process Mkt pf m y < 0 by simp
    hence "pf stk (Suc m) y  0  pf risk_free_asset (Suc m) y  0" using assms non_zero_components by simp
    thus "y. cls_val_process Mkt pf (Suc m) y < 0" using neg_pf_exists[of pf m y] assms
      val_process Mkt pf m y  0 by simp
  qed
qed




lemma (in CRR_market) viable_if:
  assumes "1+r < u"
  and "d < 1+r"
shows "viable_market Mkt" unfolding viable_market_def
proof (rule ccontr)
  assume "¬(p. stock_portfolio Mkt p  ¬ arbitrage_process Mkt p)"
  hence "p. stock_portfolio Mkt p  arbitrage_process Mkt p" by simp
  from this obtain pf where "stock_portfolio Mkt pf" and "arbitrage_process Mkt pf" by auto
  have "( m. (self_financing Mkt pf)  (trading_strategy pf) 
    (w  space M. cls_val_process Mkt pf 0 w = 0) 
    (AE w in M. 0  cls_val_process Mkt pf m w) 
    0 < 𝒫(w in M. cls_val_process Mkt pf m w > 0))" using arbitrage_process Mkt pf
    using arbitrage_processE by simp
  from this obtain m where "self_financing Mkt pf" and "(trading_strategy pf)"
    and "(w  space M. cls_val_process Mkt pf 0 w = 0)"
    and "(AE w in M. 0  cls_val_process Mkt pf m w)"
    and "0 < 𝒫(w in M. cls_val_process Mkt pf m w > 0)" by auto
  have "{w space M. cls_val_process Mkt pf m w > 0}  {}" using
    0 < 𝒫(w in M. cls_val_process Mkt pf m w > 0) by force
  hence "w space M. cls_val_process Mkt pf m w > 0" by auto
  from this obtain y where "y space M" and "cls_val_process Mkt pf m y > 0" by auto
  define A where "A = {n::nat. n  m  cls_val_process Mkt pf n y > 0}"
  have "finite A" unfolding A_def by auto
  have "m  A" using cls_val_process Mkt pf m y > 0 unfolding A_def by simp
  hence "A  {}" by auto
  hence "Min A  A" using finite A by simp
  have "Min A  m" using finite A m A by simp
  have "0 < Min A"
  proof -
    have "cls_val_process Mkt pf 0 y = 0" using y space M w  space M. cls_val_process Mkt pf 0 w = 0
      by simp
    hence "0 A" unfolding A_def by simp
    moreover have "0  Min A" by simp
    ultimately show ?thesis using Min A  A neq0_conv by fastforce
  qed
  hence "l. Suc l = Min A" using Suc_diff_1 by blast
  from this obtain l where "Suc l = Min A" by auto
  have "cls_val_process Mkt pf l y  0"
  proof -
    have "l < Min A" using Suc l = Min A by simp
    hence "l A" using finite A A  {} by auto
    moreover have "l  m" using Suc l = Min A m A finite A A  {} l < Min A by auto
    ultimately show ?thesis unfolding A_def by auto
  qed
  hence "val_process Mkt pf l y  0" using self_financing Mkt pf by (simp add:self_financingE)
  moreover have "pf stk (Suc l) y  0  pf risk_free_asset (Suc l) y  0"
  proof (rule ccontr)
    assume "¬(pf stk (Suc l) y  0  pf risk_free_asset (Suc l) y  0)"
    hence "pf stk (Suc l) y = 0" "pf risk_free_asset (Suc l) y = 0" by auto
    have "cls_val_process Mkt pf (Min A) y = geom_proc (Suc l) y * pf stk (Suc l) y +
      disc_rfr_proc r (Suc l) y * pf risk_free_asset (Suc l) y" using stock_portfolio Mkt pf
      Suc l = Min A stock_pf_uvp_expand[of pf l]  by simp
    also have "... = 0" using pf stk (Suc l) y = 0 pf risk_free_asset (Suc l) y = 0 by simp
    finally have "cls_val_process Mkt pf (Min A) y = 0" .
    moreover have "cls_val_process Mkt pf (Min A) y > 0" using Min A  A unfolding A_def by simp
    ultimately show False by simp
  qed
  ultimately have "z. cls_val_process Mkt pf (Suc l) z < 0" using assms stock_portfolio Mkt pf
    trading_strategy pf by (simp add:neg_pf_exists)
  from this obtain z where "cls_val_process Mkt pf (Suc l) z < 0" by auto
  hence "x'. cls_val_process Mkt pf m x' < 0" using neg_pf_Suc assms trading_strategy pf
      self_financing Mkt pf Suc l = Min A Min A  m stock_portfolio Mkt pf by simp
  from this obtain x' where "cls_val_process Mkt pf m x' < 0" by auto
  have "x' space M" using bernoulli_stream_space bernoulli by auto
  hence "x' {w space M. ¬0  cls_val_process Mkt pf m w}" using cls_val_process Mkt pf m x' < 0 by auto
  from AE w in M. 0  cls_val_process Mkt pf m w obtain N where
    "{w space M. ¬0  cls_val_process Mkt pf m w}  N" and "emeasure M N = 0" and "N sets M" using AE_E by auto
  have "{w space M. (stake m w = stake m x')}  N"
  proof
    fix x
    assume "x  {w  space M. stake m w = stake m x'}"
    hence "x space M" and "stake m x = stake m x'" by auto
    have "cls_val_process Mkt pf m  borel_measurable (G m)"
    proof -
      have "borel_adapt_stoch_proc G (cls_val_process Mkt pf)" using trading_strategy pf stock_portfolio Mkt pf
        by (meson support_adapt_def readable  stock_portfolio_def subsetCE cls_val_process_adapted)
      thus ?thesis unfolding adapt_stoch_proc_def by simp
    qed
    hence "cls_val_process Mkt pf m x' = cls_val_process Mkt pf m x"
      using  stake m x = stake m x' borel_measurable_stake[of "cls_val_process Mkt pf m" m x x']
      pseudo_proj_True_stake_image spickI stoch_proc_subalg_nat_filt[of geom_proc] geometric_process stock_filtration
          by (metis geom_rand_walk_borel_adapted measurable_from_subalg)
    hence "cls_val_process Mkt pf m x < 0" using cls_val_process Mkt pf m x' < 0 by simp
    thus "x N" using {w space M. ¬0  cls_val_process Mkt pf m w}  N x space M
      cls_val_process Mkt pf (Suc l) z < 0 by auto
  qed
  moreover have "emeasure M {w space M. (stake m w = stake m x')}  0" using bernoulli_stream_pref_prob_neq_zero psgt pslt by simp
  ultimately show False using emeasure M N = 0 N  events emeasure_eq_0 by blast
qed


lemma (in CRR_market) viable_only_if_d:
  assumes "viable_market Mkt"
  shows "d < 1+r"
proof (rule ccontr)
  assume "¬ d < 1+r"
  hence "1+r  d" by simp
  define arb_pf where "arb_pf = (λ (x::'a) (n::nat) w. 0::real)(stk:= (λ n w. 1), risk_free_asset := (λ n w. - geom_proc 0 w))"
  have "support_set arb_pf = {stk, risk_free_asset}"
  proof
    show "support_set arb_pf  {stk, risk_free_asset}"
      by (simp add: arb_pf_def subset_iff support_set_def)
    have "stk support_set arb_pf" unfolding arb_pf_def support_set_def using two_stocks by simp
    moreover have "risk_free_asset support_set arb_pf" unfolding arb_pf_def support_set_def
      using two_stocks geometric_process S0_positive by simp
    ultimately show "{stk, risk_free_asset} support_set arb_pf" by simp
  qed
  hence "stock_portfolio Mkt arb_pf" using stocks
    by (simp add: portfolio_def stock_portfolio_def)
  have "arbitrage_process Mkt arb_pf"
  proof (rule arbitrage_processI, intro exI conjI)
    show "self_financing Mkt arb_pf" unfolding arb_pf_def using support_set arb_pf = {stk, risk_free_asset}
      by (simp add: static_portfolio_self_financing)
    show "trading_strategy arb_pf" unfolding trading_strategy_def
    proof (intro conjI ballI)
      show "portfolio arb_pf" unfolding portfolio_def using support_set arb_pf = {stk, risk_free_asset} by simp
      fix asset
      assume "asset support_set arb_pf"
      show "borel_predict_stoch_proc G (arb_pf asset)"
      proof (cases "asset = stk")
        case True
        hence "arb_pf asset = (λ n w. 1)" unfolding arb_pf_def by (simp add: two_stocks)
        show ?thesis unfolding predict_stoch_proc_def
        proof
          show "arb_pf asset 0  borel_measurable (G 0)" using arb_pf asset = (λ n w. 1) by simp
          show "n. arb_pf asset (Suc n)  borel_measurable (G n)"
          proof
            fix n
            show "arb_pf asset (Suc n)  borel_measurable (G n)" using arb_pf asset = (λ n w. 1) by simp
          qed
        qed
      next
        case False
        hence "arb_pf asset = (λ n w. - geom_proc 0 w)" using support_set arb_pf = {stk, risk_free_asset}
          asset  support_set arb_pf unfolding arb_pf_def by simp
        show ?thesis unfolding predict_stoch_proc_def
        proof
          show "arb_pf asset 0  borel_measurable (G 0)" using arb_pf asset = (λ n w. - geom_proc 0 w)
            geometric_process by simp
          show "n. arb_pf asset (Suc n)  borel_measurable (G n)"
          proof
            fix n
            show "arb_pf asset (Suc n)  borel_measurable (G n)" using arb_pf asset = (λ n w. - geom_proc 0 w)
              geometric_process by simp
          qed
        qed
      qed
    qed
    show "wspace M. cls_val_process Mkt arb_pf 0 w = 0"
    proof
      fix w
      assume "w space M"
      have "cls_val_process Mkt arb_pf 0 w = geom_proc 0 w * arb_pf stk (Suc 0) w +
        disc_rfr_proc r 0 w * arb_pf risk_free_asset (Suc 0) w" using stock_pf_vp_expand
        stock_portfolio Mkt arb_pf
        using self_financing Mkt arb_pf self_financingE by fastforce
      also have "... = geom_proc 0 w * (1) + disc_rfr_proc r 0 w * arb_pf risk_free_asset (Suc 0) w"
        by (simp add: arb_pf_def two_stocks)
      also have "... = geom_proc 0 w + arb_pf risk_free_asset (Suc 0) w" by simp
      also have "... = geom_proc 0 w  - geom_proc 0 w" unfolding arb_pf_def by simp
      also have "... = 0" by simp
      finally show "cls_val_process Mkt arb_pf 0 w = 0" .
    qed
    have dev: "w space M. cls_val_process Mkt arb_pf (Suc 0) w = geom_proc (Suc 0) w - (1+r) * geom_proc 0 w"
    proof (intro ballI)
      fix w
      assume "w space M"
      have "cls_val_process Mkt arb_pf (Suc 0) w =  geom_proc (Suc 0) w * arb_pf stk (Suc 0) w +
        disc_rfr_proc r (Suc 0) w * arb_pf risk_free_asset (Suc 0) w" using stock_pf_uvp_expand
        stock_portfolio Mkt arb_pf by simp
      also have "... = geom_proc (Suc 0) w + disc_rfr_proc r (Suc 0) w * arb_pf risk_free_asset (Suc 0) w"
        by (simp add: arb_pf_def two_stocks)
      also have "... = geom_proc (Suc 0) w + (1+r) * arb_pf risk_free_asset (Suc 0) w" by simp
      also have "... = geom_proc (Suc 0) w - (1+r) * geom_proc 0 w" by (simp add:arb_pf_def)
      finally show "cls_val_process Mkt arb_pf (Suc 0) w = geom_proc (Suc 0) w - (1+r) * geom_proc 0 w" .
    qed
    have iniT: "w space M. snth w 0  cls_val_process Mkt arb_pf (Suc 0) w > 0"
    proof (intro ballI impI)
      fix w
      assume "w space M" and "snth w 0"
      have "cls_val_process Mkt arb_pf (Suc 0) w =  geom_proc (Suc 0) w - (1+r) * geom_proc 0 w"
        using dev w space M by simp
      also have "... = u * geom_proc 0 w - (1+r) * geom_proc 0 w" using snth w 0 geometric_process by simp
      also have "... = (u - (1+r)) * geom_proc 0 w" by (simp add: left_diff_distrib)
      also have "... > 0" using S0_positive 1 + r  d down_lt_up geometric_process by auto
      finally show "cls_val_process Mkt arb_pf (Suc 0) w > 0" .
    qed
    have iniF: "w space M. ¬snth w 0  cls_val_process Mkt arb_pf (Suc 0) w  0"
    proof (intro ballI impI)
      fix w
      assume "w space M" and "¬snth w 0"
      have "cls_val_process Mkt arb_pf (Suc 0) w =  geom_proc (Suc 0) w - (1+r) * geom_proc 0 w"
        using dev w space M by simp
      also have "... = d * geom_proc 0 w - (1+r) * geom_proc 0 w" using ¬snth w 0 geometric_process by simp
      also have "... = (d - (1+r)) * geom_proc 0 w" by (simp add: left_diff_distrib)
      also have "...  0" using S0_positive 1 + r  d down_lt_up geometric_process by auto
      finally show "cls_val_process Mkt arb_pf (Suc 0) w  0" .
    qed
    have "w space M. cls_val_process Mkt arb_pf (Suc 0) w  0"
    proof
      fix w
      assume "w space M"
      show "cls_val_process Mkt arb_pf (Suc 0) w  0"
      proof (cases "snth w 0")
        case True
        thus ?thesis using w space M iniT by auto
      next
        case False
        thus ?thesis using w space M iniF by simp
      qed
    qed
    thus "AE w in M. 0  cls_val_process Mkt arb_pf (Suc 0) w" by simp
    show "0 < prob {w  space M. 0 < cls_val_process Mkt arb_pf (Suc 0) w}"
    proof -
      have "cls_val_process Mkt arb_pf (Suc 0)  borel_measurable M" using borel_adapt_stoch_proc_borel_measurable
        cls_val_process_adapted trading_strategy arb_pf stock_portfolio Mkt arb_pf
        using support_adapt_def readable unfolding  stock_portfolio_def by blast
      hence set_event:"{w  space M. 0 < cls_val_process Mkt arb_pf (Suc 0) w}  sets M"
        using borel_measurable_iff_greater by blast
      have "n. emeasure M {w  space M. w !! n} = ennreal p"
        using bernoulli p_gt_0 p_lt_1 bernoulli_stream_component_probability[of M p]
        by auto
      hence "emeasure M {w  space M. w !! 0} = ennreal p" by blast
      moreover have "{w  space M. w !! 0}  {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}"
      proof
        fix w
        assume "w {w  space M. w !! 0}"
        hence "w  space M" and "w !! 0" by auto note wprops = this
        hence "0 < cls_val_process Mkt arb_pf 1 w" using iniT by simp
        thus "w {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}" using wprops by simp
      qed
      ultimately have "p  emeasure M {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}"
        using emeasure_mono set_event by fastforce
      hence "p  prob {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}" by (simp add: emeasure_eq_measure)
      thus "0 < prob {w  space M. 0 < cls_val_process Mkt arb_pf (Suc 0) w}" using psgt by simp
    qed
  qed
  thus False using assms unfolding viable_market_def using stock_portfolio Mkt arb_pf by simp
qed


lemma (in CRR_market) viable_only_if_u:
  assumes "viable_market Mkt"
  shows "1+r < u"
proof (rule ccontr)
  assume "¬ 1+r < u"
  hence "u  1+r" by simp
  define arb_pf where "arb_pf = (λ (x::'a) (n::nat) w. 0::real)(stk:= (λ n w. -1), risk_free_asset := (λ n w. geom_proc 0 w))"
  have "support_set arb_pf = {stk, risk_free_asset}"
  proof
    show "support_set arb_pf  {stk, risk_free_asset}"
      by (simp add: arb_pf_def subset_iff support_set_def)
    have "stk support_set arb_pf" unfolding arb_pf_def support_set_def using two_stocks by simp
    moreover have "risk_free_asset support_set arb_pf" unfolding arb_pf_def support_set_def
      using two_stocks geometric_process S0_positive by simp
    ultimately show "{stk, risk_free_asset} support_set arb_pf" by simp
  qed
  hence "stock_portfolio Mkt arb_pf" using stocks
    by (simp add: portfolio_def stock_portfolio_def)
  have "arbitrage_process Mkt arb_pf"
  proof (rule arbitrage_processI, intro exI conjI)
    show "self_financing Mkt arb_pf" unfolding arb_pf_def using support_set arb_pf = {stk, risk_free_asset}
      by (simp add: static_portfolio_self_financing)
    show "trading_strategy arb_pf" unfolding trading_strategy_def
    proof (intro conjI ballI)
      show "portfolio arb_pf" unfolding portfolio_def using support_set arb_pf = {stk, risk_free_asset} by simp
      fix asset
      assume "asset support_set arb_pf"
      show "borel_predict_stoch_proc G (arb_pf asset)"
      proof (cases "asset = stk")
        case True
        hence "arb_pf asset = (λ n w. -1)" unfolding arb_pf_def by (simp add: two_stocks)
        show ?thesis unfolding predict_stoch_proc_def
        proof
          show "arb_pf asset 0  borel_measurable (G 0)" using arb_pf asset = (λ n w. -1) by simp
          show "n. arb_pf asset (Suc n)  borel_measurable (G n)"
          proof
            fix n
            show "arb_pf asset (Suc n)  borel_measurable (G n)" using arb_pf asset = (λ n w. -1) by simp
          qed
        qed
      next
        case False
        hence "arb_pf asset = (λ n w. geom_proc 0 w)" using support_set arb_pf = {stk, risk_free_asset}
          asset  support_set arb_pf unfolding arb_pf_def by simp
        show ?thesis unfolding predict_stoch_proc_def
        proof
          show "arb_pf asset 0  borel_measurable (G 0)" using arb_pf asset = (λ n w. geom_proc 0 w)
            geometric_process by simp
          show "n. arb_pf asset (Suc n)  borel_measurable (G n)"
          proof
            fix n
            show "arb_pf asset (Suc n)  borel_measurable (G n)" using arb_pf asset = (λ n w. geom_proc 0 w)
              geometric_process by simp
          qed
        qed
      qed
    qed
    show "wspace M. cls_val_process Mkt arb_pf 0 w = 0"
    proof
      fix w
      assume "w space M"
      have "cls_val_process Mkt arb_pf 0 w = geom_proc 0 w * arb_pf stk (Suc 0) w +
        disc_rfr_proc r 0 w * arb_pf risk_free_asset (Suc 0) w" using stock_pf_vp_expand
        stock_portfolio Mkt arb_pf
        using self_financing Mkt arb_pf self_financingE by fastforce
      also have "... = geom_proc 0 w * (-1) + disc_rfr_proc r 0 w * arb_pf risk_free_asset (Suc 0) w"
        by (simp add: arb_pf_def two_stocks)
      also have "... = -geom_proc 0 w + arb_pf risk_free_asset (Suc 0) w" by simp
      also have "... = geom_proc 0 w  - geom_proc 0 w" unfolding arb_pf_def by simp
      also have "... = 0" by simp
      finally show "cls_val_process Mkt arb_pf 0 w = 0" .
    qed
    have dev: "w space M. cls_val_process Mkt arb_pf (Suc 0) w = -geom_proc (Suc 0) w + (1+r) * geom_proc 0 w"
    proof (intro ballI)
      fix w
      assume "w space M"
      have "cls_val_process Mkt arb_pf (Suc 0) w =  geom_proc (Suc 0) w * arb_pf stk (Suc 0) w +
        disc_rfr_proc r (Suc 0) w * arb_pf risk_free_asset (Suc 0) w" using stock_pf_uvp_expand
        stock_portfolio Mkt arb_pf by simp
      also have "... = -geom_proc (Suc 0) w + disc_rfr_proc r (Suc 0) w * arb_pf risk_free_asset (Suc 0) w"
        by (simp add: arb_pf_def two_stocks)
      also have "... = -geom_proc (Suc 0) w + (1+r) * arb_pf risk_free_asset (Suc 0) w" by simp
      also have "... = -geom_proc (Suc 0) w + (1+r) * geom_proc 0 w" by (simp add:arb_pf_def)
      finally show "cls_val_process Mkt arb_pf (Suc 0) w = -geom_proc (Suc 0) w + (1+r) * geom_proc 0 w" .
    qed
    have iniT: "w space M. snth w 0  cls_val_process Mkt arb_pf (Suc 0) w  0"
    proof (intro ballI impI)
      fix w
      assume "w space M" and "snth w 0"
      have "cls_val_process Mkt arb_pf (Suc 0) w =  -geom_proc (Suc 0) w + (1+r) * geom_proc 0 w"
        using dev w space M by simp
      also have "... = - u * geom_proc 0 w + (1+r) * geom_proc 0 w" using snth w 0 geometric_process by simp
      also have "... = (-u + (1+r)) * geom_proc 0 w" by (simp add: left_diff_distrib)
      also have "...  0" using S0_positive u 1 + r down_lt_up geometric_process by auto
      finally show "cls_val_process Mkt arb_pf (Suc 0) w  0" .
    qed
    have iniF: "w space M. ¬snth w 0  cls_val_process Mkt arb_pf (Suc 0) w > 0"
    proof (intro ballI impI)
      fix w
      assume "w space M" and "¬snth w 0"
      have "cls_val_process Mkt arb_pf (Suc 0) w =  -geom_proc (Suc 0) w + (1+r) * geom_proc 0 w"
        using dev w space M by simp
      also have "... = -d * geom_proc 0 w + (1+r) * geom_proc 0 w" using ¬snth w 0 geometric_process by simp
      also have "... = (-d + (1+r)) * geom_proc 0 w" by (simp add: left_diff_distrib)
      also have "... > 0" using S0_positive u <= 1 + r down_lt_up geometric_process by auto
      finally show "cls_val_process Mkt arb_pf (Suc 0) w > 0" .
    qed
    have "w space M. cls_val_process Mkt arb_pf (Suc 0) w  0"
    proof
      fix w
      assume "w space M"
      show "cls_val_process Mkt arb_pf (Suc 0) w  0"
      proof (cases "snth w 0")
        case True
        thus ?thesis using w space M iniT by simp
      next
        case False
        thus ?thesis using w space M iniF by auto
      qed
    qed
    thus "AE w in M. 0  cls_val_process Mkt arb_pf (Suc 0) w" by simp
    show "0 < prob {w  space M. 0 < cls_val_process Mkt arb_pf (Suc 0) w}"
    proof -
      have "cls_val_process Mkt arb_pf (Suc 0)  borel_measurable M" using borel_adapt_stoch_proc_borel_measurable
        cls_val_process_adapted trading_strategy arb_pf stock_portfolio Mkt arb_pf
         using support_adapt_def readable unfolding stock_portfolio_def by blast
      hence set_event:"{w  space M. 0 < cls_val_process Mkt arb_pf (Suc 0) w}  sets M"
        using borel_measurable_iff_greater by blast
      have "n. emeasure M {w  space M. ¬w !! n} = ennreal (1-p)"
        using bernoulli p_gt_0 p_lt_1 bernoulli_stream_component_probability_compl[of M p]
        by auto
      hence "emeasure M {w  space M. ¬w !! 0} = ennreal (1-p)" by blast
      moreover have "{w  space M. ¬w !! 0}  {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}"
      proof
        fix w
        assume "w {w  space M. ¬w !! 0}"
        hence "w  space M" and "¬w !! 0" by auto note wprops = this
        hence "0 < cls_val_process Mkt arb_pf 1 w" using iniF by simp
        thus "w {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}" using wprops by simp
      qed
      ultimately have "1-p  emeasure M {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}"
        using emeasure_mono set_event by fastforce
      hence "1-p  prob {w  space M. 0 < cls_val_process Mkt arb_pf 1 w}" by (simp add: emeasure_eq_measure)
      thus "0 < prob {w  space M. 0 < cls_val_process Mkt arb_pf (Suc 0) w}" using pslt by simp
    qed
  qed
  thus False using assms unfolding viable_market_def using stock_portfolio Mkt arb_pf by simp
qed

lemma (in CRR_market) viable_iff:
shows "viable_market Mkt  (d < 1+r  1+r < u)" using viable_if viable_only_if_d viable_only_if_u by auto


subsection ‹Risk-neutral probability space for the geometric random walk›



lemma (in CRR_market) stock_price_borel_measurable:
  shows "borel_adapt_stoch_proc G (prices Mkt stk)"
proof -
  have "borel_adapt_stoch_proc (stoch_proc_filt M geom_proc borel) (prices Mkt stk)"
    by (simp add: geom_rand_walk_borel_measurable stk_price stoch_proc_filt_adapt)
  thus ?thesis by (simp add:stock_filtration)
qed


lemma (in CRR_market) risk_free_asset_martingale:
  assumes "N = bernoulli_stream q"
  and "0 < q"
  and "q < 1"
  shows "martingale N G (discounted_value r (prices Mkt risk_free_asset))"
proof -
  have "filtration N G" by (simp add: assms bernoulli_gen_filtration)
  moreover have "n. sigma_finite_subalgebra N (G n)" by (simp add: assms bernoulli_sigma_finite)
  moreover have "finite_measure N" using assms bernoulli_stream_def prob_space.prob_space_stream_space
    prob_space_def prob_space_measure_pmf by auto
  moreover have "discounted_value r (prices Mkt risk_free_asset) = (λ n w. 1)" using discounted_rfr by auto
  ultimately show ?thesis using finite_measure.constant_martingale by simp
qed


lemma (in infinite_coin_toss_space) nat_filtration_from_eq_sets:
  assumes "N = bernoulli_stream q"
  and "0 < q"
  and "q < 1"
shows "sets (infinite_coin_toss_space.nat_filtration N n) = sets (nat_filtration n)"
proof -
  have "sigma_sets (space (bernoulli_stream q)) {pseudo_proj_True n -` B  space N |B. B  sets (bernoulli_stream q)} = sigma_sets (space (bernoulli_stream p))
          {pseudo_proj_True n -` B  space M |B. B  sets (bernoulli_stream p)}"
  proof -
    have "sets N = events"
      by (metis assms(1) bernoulli_stream_def infinite_coin_toss_space_axioms infinite_coin_toss_space_def sets_measure_pmf sets_stream_space_cong)
    then show ?thesis
      using assms(1) bernoulli_stream_space infinite_coin_toss_space_axioms infinite_coin_toss_space_def by auto
  qed
  thus ?thesis using infinite_coin_toss_space.nat_filtration_sets
    using assms(1) assms(2) assms(3) infinite_coin_toss_space_axioms infinite_coin_toss_space_def by auto
qed




lemma (in CRR_market) geom_proc_integrable:
  assumes "N = bernoulli_stream q"
and "0  q"
and "q  1"
shows "integrable N (geom_proc n)"
proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
  show "infinite_coin_toss_space q N" using assms by unfold_locales
  show "geom_proc n  borel_measurable (infinite_coin_toss_space.nat_filtration N n)" using geometric_process
    prob_grw.geom_rand_walk_borel_adapted[of q N geom_proc u d init]
    by (metis infinite_coin_toss_space q N geom_rand_walk_pseudo_proj_True infinite_coin_toss_space.nat_filtration_borel_measurable_characterization
         prob_grw.geom_rand_walk_borel_measurable prob_grw_axioms prob_grw_def)
qed

lemma (in CRR_market) CRR_infinite_cts_filtration:
  shows "infinite_cts_filtration p M nat_filtration"
  by (unfold_locales, simp)


lemma (in CRR_market) proj_stoch_proc_geom_disc_fct:
  shows "disc_fct (proj_stoch_proc geom_proc n)" unfolding disc_fct_def using CRR_infinite_cts_filtration
    by (simp add: countable_finite geom_rand_walk_borel_adapted infinite_cts_filtration.proj_stoch_set_finite_range)

lemma (in CRR_market) proj_stoch_proc_geom_rng:
  assumes "N = bernoulli_stream q"
shows  "proj_stoch_proc geom_proc n  N M stream_space borel"
proof -
  have "random_variable (stream_space borel) (proj_stoch_proc geom_proc n)" using CRR_infinite_cts_filtration
    using geom_rand_walk_borel_adapted nat_discrete_filtration proj_stoch_measurable_if_adapted by blast
  then show ?thesis
    using assms(1) bernoulli bernoulli_stream_def by auto
qed

lemma (in CRR_market) proj_stoch_proc_geom_open_set:
  shows  "rrange (proj_stoch_proc geom_proc n)  space (stream_space borel).
     Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}"
proof
  fix r
  assume "r range (proj_stoch_proc geom_proc n)  space (stream_space borel)"
  show "Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}"
  proof
    show "infinite_cts_filtration.stream_space_single (proj_stoch_proc geom_proc n) r  sets (stream_space borel)"
      using infinite_cts_filtration.stream_space_single_set r  range (proj_stoch_proc geom_proc n)  space (stream_space borel)
        geom_rand_walk_borel_adapted CRR_infinite_cts_filtration by blast
    show "range (proj_stoch_proc geom_proc n)  infinite_cts_filtration.stream_space_single (proj_stoch_proc geom_proc n) r = {r}"
      using infinite_cts_filtration.stream_space_single_preimage r  range (proj_stoch_proc geom_proc n)  space (stream_space borel)
        geom_rand_walk_borel_adapted CRR_infinite_cts_filtration by blast
  qed
qed

lemma (in CRR_market) bernoulli_AE_cond_exp:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
and "integrable N X"
shows "AE w in N. real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)) X w =
    expl_cond_expect N (proj_stoch_proc geom_proc n) X w"
proof (rule finite_measure.charact_cond_exp')
  have "infinite_cts_filtration p M nat_filtration"
    by (unfold_locales, simp)
  show "finite_measure N" using assms
    by (simp add: bernoulli_stream_def prob_space.finite_measure prob_space.prob_space_stream_space prob_space_measure_pmf)
  show "disc_fct (proj_stoch_proc geom_proc n)" using proj_stoch_proc_geom_disc_fct by simp
  show "integrable N X"  using assms by simp
  show "proj_stoch_proc geom_proc n  N M stream_space borel" using assms proj_stoch_proc_geom_rng by simp
  show "rrange (proj_stoch_proc geom_proc n)  space (stream_space borel).
     Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}"
    using proj_stoch_proc_geom_open_set by simp
qed

lemma (in CRR_market) geom_proc_cond_exp:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "AE w in N. real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)) (geom_proc (Suc n)) w =
    expl_cond_expect N (proj_stoch_proc geom_proc n) (geom_proc (Suc n)) w"
proof (rule bernoulli_AE_cond_exp)
  show "integrable N (geom_proc (Suc n))"  using assms geom_proc_integrable[of N q "Suc n"] by simp
qed (auto simp add: assms)


lemma (in CRR_market) expl_cond_eq_sets:
  assumes "N = bernoulli_stream q"
  shows  "expl_cond_expect N (proj_stoch_proc geom_proc n) X 
        borel_measurable (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
proof (rule expl_cond_exp_borel)
  show "proj_stoch_proc geom_proc n  space N  space (stream_space borel)"
  proof -
    have "random_variable (stream_space borel) (proj_stoch_proc geom_proc n)"
      using CRR_infinite_cts_filtration geom_rand_walk_borel_adapted proj_stoch_measurable_if_adapted
        nat_discrete_filtration by blast
    then show ?thesis
      by (simp add: assms(1) bernoulli bernoulli_stream_space measurable_def)
  qed
  show "disc_fct (proj_stoch_proc geom_proc n)" unfolding disc_fct_def using CRR_infinite_cts_filtration
    by (simp add: countable_finite geom_rand_walk_borel_adapted infinite_cts_filtration.proj_stoch_set_finite_range)
  show "rrange (proj_stoch_proc geom_proc n)  space (stream_space borel).
    Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}"
  proof
    fix r
    assume "rrange (proj_stoch_proc geom_proc n)  space (stream_space borel)"
    show "Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}"
    proof
      show "infinite_cts_filtration.stream_space_single (proj_stoch_proc geom_proc n) r  sets (stream_space borel)"
        using infinite_cts_filtration.stream_space_single_set r  range (proj_stoch_proc geom_proc n)  space (stream_space borel)
          geom_rand_walk_borel_adapted CRR_infinite_cts_filtration by blast
      show "range (proj_stoch_proc geom_proc n)  infinite_cts_filtration.stream_space_single (proj_stoch_proc geom_proc n) r = {r}"
        using infinite_cts_filtration.stream_space_single_preimage r  range (proj_stoch_proc geom_proc n)  space (stream_space borel)
          geom_rand_walk_borel_adapted CRR_infinite_cts_filtration by blast
    qed
  qed
qed


lemma (in CRR_market) bernoulli_real_cond_exp_AE:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
and "integrable N X"
shows "real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))
   X w = expl_cond_expect N (proj_stoch_proc geom_proc n) X w"
proof -
  have "real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))
   X w = expl_cond_expect N (proj_stoch_proc geom_proc n) X w"
  proof (rule infinite_coin_toss_space.nat_filtration_AE_eq)
    show "infinite_coin_toss_space q N" using assms
      by (simp add: infinite_coin_toss_space_def)
    show "AE w in N. real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)) X w =
    expl_cond_expect N (proj_stoch_proc geom_proc n) X w"  using assms bernoulli_AE_cond_exp by simp
    show "real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)) X
       borel_measurable (infinite_coin_toss_space.nat_filtration N n)"
    proof -
      have "real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)) X
         borel_measurable (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
        by simp
      moreover have "subalgebra (infinite_coin_toss_space.nat_filtration N n) (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
        using stock_filtration infinite_coin_toss_space.stoch_proc_subalg_nat_filt[of q N geom_proc n]
        infinite_cts_filtration.stoch_proc_filt_gen[of q N]
        by (metis infinite_coin_toss_space q N infinite_cts_filtration_axioms.intro infinite_cts_filtration_def
            prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      ultimately show ?thesis using measurable_from_subalg by blast
    qed
    show "expl_cond_expect N (proj_stoch_proc geom_proc n) X 
      borel_measurable (infinite_coin_toss_space.nat_filtration N n)"
    proof -
      have "expl_cond_expect N (proj_stoch_proc geom_proc n) X 
        borel_measurable (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
        by (simp add: expl_cond_eq_sets assms)
      moreover have "subalgebra (infinite_coin_toss_space.nat_filtration N n) (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
      using stock_filtration infinite_coin_toss_space.stoch_proc_subalg_nat_filt[of q N geom_proc n]
        infinite_cts_filtration.stoch_proc_filt_gen[of q N]
        by (metis infinite_coin_toss_space q N infinite_cts_filtration_axioms.intro infinite_cts_filtration_def
            prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      ultimately show ?thesis using measurable_from_subalg by blast
    qed
    show "0 < q" and "q < 1" using assms by auto
  qed
  thus ?thesis by simp
qed

lemma (in CRR_market) geom_proc_real_cond_exp_AE:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))
   (geom_proc (Suc n)) w = expl_cond_expect N (proj_stoch_proc geom_proc n) (geom_proc (Suc n)) w"
proof (rule bernoulli_real_cond_exp_AE)
show "integrable N (geom_proc (Suc n))"  using assms geom_proc_integrable[of N q "Suc n"] by simp
qed (auto simp add: assms)


lemma (in CRR_market) geom_proc_stoch_proc_filt:
  assumes "N= bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "stoch_proc_filt N geom_proc borel n = fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)"
proof (rule infinite_cts_filtration.stoch_proc_filt_gen)
  show "infinite_cts_filtration q N (infinite_coin_toss_space.nat_filtration N)" unfolding infinite_cts_filtration_def
  proof
    show "infinite_coin_toss_space q N" using assms
      by (simp add: infinite_coin_toss_space_def)
    show "infinite_cts_filtration_axioms N (infinite_coin_toss_space.nat_filtration N)"
      using infinite_cts_filtration_axioms_def by blast
  qed
  show "borel_adapt_stoch_proc (infinite_coin_toss_space.nat_filtration N) geom_proc"
    using infinite_cts_filtration q N (infinite_coin_toss_space.nat_filtration N)
      prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def
    using infinite_cts_filtration_def by auto
qed

lemma (in CRR_market) bernoulli_cond_exp:
  assumes "N = bernoulli_stream q"
  and "0 < q"
  and "q < 1"
and "integrable N X"
shows "real_cond_exp N (stoch_proc_filt N geom_proc borel n) X w = expl_cond_expect N (proj_stoch_proc geom_proc n) X w"
proof -
  have aeq: "AE w in N. real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)) X w =
    expl_cond_expect N (proj_stoch_proc geom_proc n) X w"  using assms
    bernoulli_AE_cond_exp by simp
  have "w. real_cond_exp N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))
   X w = expl_cond_expect N (proj_stoch_proc geom_proc n) X w"  using assms bernoulli_real_cond_exp_AE by simp
  moreover have "stoch_proc_filt N geom_proc borel n = fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)"
    using assms geom_proc_stoch_proc_filt by simp
  ultimately show ?thesis by simp
qed

lemma (in CRR_market) stock_cond_exp:
  assumes "N = bernoulli_stream q"
  and "0 < q"
  and "q < 1"
shows "real_cond_exp N (stoch_proc_filt N geom_proc borel n) (geom_proc (Suc n)) w = expl_cond_expect N (proj_stoch_proc geom_proc n) (geom_proc (Suc n)) w"
proof (rule bernoulli_cond_exp)
show "integrable N (geom_proc (Suc n))"  using assms geom_proc_integrable[of N q "Suc n"] by simp
qed (auto simp add: assms)




lemma (in prob_space) discount_factor_real_cond_exp:
  assumes "integrable M X"
and "subalgebra M G"
and "-1 < r"
shows "AE w in M. real_cond_exp M G (λx. discount_factor r n x * X x) w = discount_factor r n w * (real_cond_exp M G X) w"
proof (rule sigma_finite_subalgebra.real_cond_exp_mult)
  show "sigma_finite_subalgebra M G" using assms subalgebra_sigma_finite by simp
  show "discount_factor r n  borel_measurable G" by (simp add: discount_factor_borel_measurable)
  show "random_variable borel X" using assms by simp
  show "integrable M (λx. discount_factor r n x * X x)"  using assms discounted_integrable[of M "λn. X"]
    unfolding discounted_value_def by simp
qed


lemma (in prob_space) discounted_value_real_cond_exp:
  assumes "integrable M X"
  and "-1 < r"
and "subalgebra M G"
  shows "AE w in M. real_cond_exp M G ((discounted_value r (λ m. X)) n) w =
    discounted_value r (λm. (real_cond_exp M G X)) n w" using  assms
  unfolding discounted_value_def  init_triv_filt_def filtration_def
  by (simp add: assms discount_factor_real_cond_exp)


lemma (in CRR_market)
  assumes "q = (1 + r - d)/(u -d)"
  and "viable_market Mkt"
  shows gt_param: "0 < q"
    and lt_param: "q < 1"
    and risk_neutral_param: "u * q + d * (1 - q) = 1 + r"
proof -
  show "0 < q" using  down_lt_up viable_only_if_d assms by simp
  show "q < 1" using down_lt_up viable_only_if_u assms by simp
  show "u * q + d * (1 - q) = 1 + r"
  proof -
    have "1 - q = 1 - (1 + r - d) / (u - d)" using assms by simp
    also have "... = (u - d)/(u - d) - (1 + r - d) / (u - d)" using down_lt_up by simp
    also have "... = (u - d - (1 + r - d))/(u-d)" using  diff_divide_distrib[of "u - d" "1 + r -d" "u -d"] by simp
    also have "... = (u - 1 - r)/(u-d)" by simp
    finally have "1 - q = (u - 1 - r)/(u -d)" .
    hence "u * q + d * (1 - q) = u * (1 + r - d)/(u - d) + d * (u - 1 - r)/(u - d)" using assms by simp
    also have "... = (u * (1 + r - d) + d * (u - 1 - r))/(u - d)" using add_divide_distrib[of "u * (1 + r - d)"] by simp
    also have "... = (u * (1 + r) - u * d + d * u - d * (1 + r))/(u - d)"
      by (simp add: diff_diff_add right_diff_distrib')
    also have "... = (u * (1+r) - d * (1+r))/(u - d)" by simp
    also have "... = ((u - d) * (1+r))/(u - d)" by (simp add: left_diff_distrib)
    also have "... = 1 + r" using down_lt_up by simp
    finally show ?thesis .
  qed
qed

lemma (in CRR_market) bernoulli_expl_cond_expect_adapt:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
  shows "expl_cond_expect N (proj_stoch_proc geom_proc n) f borel_measurable (G n)"
proof -
  have "sets N = sets M" using assms by (simp add: bernoulli bernoulli_stream_def sets_stream_space_cong)
  have icf: "infinite_cts_filtration p M nat_filtration" by (unfold_locales, simp)
  have "G n = stoch_proc_filt M geom_proc borel n" using stock_filtration by simp
  also have "... = fct_gen_subalgebra M (stream_space borel) (proj_stoch_proc geom_proc n)"
  proof (rule infinite_cts_filtration.stoch_proc_filt_gen)
    show "infinite_cts_filtration p M nat_filtration" using icf .
    show "borel_adapt_stoch_proc nat_filtration geom_proc" using geom_rand_walk_borel_adapted .
  qed
  also have "... = fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)"
    by (rule fct_gen_subalgebra_eq_sets, (simp add: sets N = sets M))
  finally have "G n = fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n)" .
  moreover have "expl_cond_expect N (proj_stoch_proc geom_proc n) f 
    borel_measurable (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
    by (simp add: expl_cond_eq_sets assms)
  ultimately show ?thesis by simp
qed



lemma (in CRR_market) real_cond_exp_discount_stock:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "AE w in N. real_cond_exp N (G n)
   (discounted_value r (prices Mkt stk) (Suc n)) w =
                  discounted_value r (λm w. (q * u + (1 - q) * d) * prices Mkt stk n w) (Suc n) w"
proof -
  have qlt: "0 < q" and qgt: "q < 1" using assms by auto
  have "G n = (fct_gen_subalgebra M (stream_space borel)
                                (proj_stoch_proc geom_proc n))"
    using stock_filtration infinite_cts_filtration.stoch_proc_filt_gen[of p M nat_filtration geom_proc n] geometric_process
      geom_rand_walk_borel_adapted CRR_infinite_cts_filtration by simp
  also have "... = (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))"
  proof (rule fct_gen_subalgebra_eq_sets)
    show "events = sets N" using assms qlt qgt
      by (simp add: bernoulli bernoulli_stream_def sets_stream_space_cong)
  qed
  finally have "G n = (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))" .
  hence "AE w in N. real_cond_exp N (G n)
   (discounted_value r (prices Mkt stk) (Suc n)) w = real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))
                                (discounted_value r (prices Mkt stk) (Suc n)) w" by simp
  moreover have "AE w in N. real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))
                                (discounted_value r (prices Mkt stk) (Suc n)) w =
                            real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))
                                (discounted_value r (λm. (prices Mkt stk) (Suc n)) (Suc n)) w"
  proof -
    have "w. (discounted_value r (prices Mkt stk) (Suc n)) w =
      (discounted_value r (λm. (prices Mkt stk) (Suc n)) (Suc n)) w"
    proof
      fix w
      show "discounted_value r (prices Mkt stk) (Suc n) w = discounted_value r (λm. prices Mkt stk (Suc n)) (Suc n) w"
        by (simp add: discounted_value_def)
    qed
    hence "(discounted_value r (prices Mkt stk) (Suc n)) =
      (discounted_value r (λm. (prices Mkt stk) (Suc n)) (Suc n))" by auto
    thus ?thesis by simp
    qed
  moreover have "AE w in N. (real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))
                                (discounted_value r (λm. (prices Mkt stk) (Suc n)) (Suc n))) w =
               discounted_value r (λm. real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                                     (proj_stoch_proc geom_proc n))
                                                     ((prices Mkt stk) (Suc n))) (Suc n) w"
  proof (rule prob_space.discounted_value_real_cond_exp)
    show "-1 < r" using acceptable_rate by simp
    show "integrable N (prices Mkt stk (Suc n))" using stk_price geom_proc_integrable assms qlt qgt by simp
    show "subalgebra N (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc n))"
    proof (rule fct_gen_subalgebra_is_subalgebra)
      show "proj_stoch_proc geom_proc n  N M stream_space borel"
      proof -
        have "proj_stoch_proc geom_proc n  measurable M (stream_space borel)"
        proof (rule proj_stoch_measurable_if_adapted)
          show "borel_adapt_stoch_proc nat_filtration geom_proc" using
            geometric_process
            geom_rand_walk_borel_adapted by simp
          show "filtration M nat_filtration" using CRR_infinite_cts_filtration
            by (simp add: nat_discrete_filtration)
        qed
        thus ?thesis using assms bernoulli_stream_equiv filt_equiv_measurable qlt qgt psgt pslt by blast
      qed
    qed
    show "prob_space N" using assms
      by (simp add: bernoulli bernoulli_stream_def prob_space.prob_space_stream_space prob_space_measure_pmf)
  qed
  moreover have "AE w in N. discounted_value r (λm. real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                                     (proj_stoch_proc geom_proc n))
                                                     ((prices Mkt stk) (Suc n))) (Suc n) w =
                    discounted_value r (λm w. (q * u + (1 - q) * d) * prices Mkt stk n w) (Suc n) w"
  proof (rule discounted_AE_cong)
   have "AEeq N (real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                (proj_stoch_proc geom_proc n))
                                ((prices Mkt stk) (Suc n)))
               (λw. q * (prices Mkt stk) (Suc n) (pseudo_proj_True n w) +
                (1 - q) * (prices Mkt stk) (Suc n) (pseudo_proj_False n w))"
     proof (rule infinite_cts_filtration.f_borel_Suc_real_cond_exp)
      show icf: "infinite_cts_filtration q N (infinite_coin_toss_space.nat_filtration N)" unfolding infinite_cts_filtration_def
      proof
        show "infinite_coin_toss_space q N" using assms qlt qgt
          by (simp add: infinite_coin_toss_space_def)
        show "infinite_cts_filtration_axioms N (infinite_coin_toss_space.nat_filtration N)"
          using infinite_cts_filtration_axioms_def by blast
      qed
      have badapt: "borel_adapt_stoch_proc (infinite_coin_toss_space.nat_filtration N) (prices Mkt stk)"
        using stk_price prob_grw.geom_rand_walk_borel_adapted[of q N  geom_proc]
        unfolding adapt_stoch_proc_def
        by (metis (full_types) borel_measurable_integrable geom_proc_integrable geom_rand_walk_pseudo_proj_True icf
            infinite_coin_toss_space.nat_filtration_borel_measurable_characterization infinite_coin_toss_space_def
            infinite_cts_filtration_def)
      show "prices Mkt stk (Suc n)  borel_measurable (infinite_coin_toss_space.nat_filtration N (Suc n))"
        using badapt unfolding adapt_stoch_proc_def by simp
      show "proj_stoch_proc geom_proc n  infinite_coin_toss_space.nat_filtration N n M stream_space borel"
      proof (rule proj_stoch_adapted_if_adapted)
        show "filtration N (infinite_coin_toss_space.nat_filtration N)" using icf
          using infinite_coin_toss_space.nat_discrete_filtration infinite_cts_filtration_def by blast
        show "borel_adapt_stoch_proc (infinite_coin_toss_space.nat_filtration N) geom_proc" using badapt stk_price by simp
      qed
      show "set_discriminating n (proj_stoch_proc geom_proc n) (stream_space borel)" unfolding set_discriminating_def
      proof (intro allI impI)
        fix w
        assume "proj_stoch_proc geom_proc n w  proj_stoch_proc geom_proc n (pseudo_proj_True n w)"
        hence False using CRR_infinite_cts_filtration
          by (metis proj_stoch_proc geom_proc n w  proj_stoch_proc geom_proc n (pseudo_proj_True n w)
            geom_rand_walk_borel_adapted infinite_cts_filtration.proj_stoch_proj_invariant)
        thus "Asets (stream_space borel).
      (proj_stoch_proc geom_proc n w  A) = (proj_stoch_proc geom_proc n (pseudo_proj_True n w)  A)" by simp
      qed
      show "w. proj_stoch_proc geom_proc n -` {proj_stoch_proc geom_proc n w} 
        sets (infinite_coin_toss_space.nat_filtration N n)"
      proof
        fix w
        show "proj_stoch_proc geom_proc n -` {proj_stoch_proc geom_proc n w}  sets (infinite_coin_toss_space.nat_filtration N n)"
          using proj_stoch_proc geom_proc n  infinite_coin_toss_space.nat_filtration N n M stream_space borel
          using assms geom_rand_walk_borel_adapted nat_filtration_from_eq_sets   qlt qgt
            infinite_cts_filtration.proj_stoch_singleton_set CRR_infinite_cts_filtration by blast
      qed
      show "rrange (proj_stoch_proc geom_proc n)  space (stream_space borel).
        Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}"
      proof
        fix r
        assume asm: "r  range (proj_stoch_proc geom_proc n)  space (stream_space borel)"
        define A where "A = infinite_cts_filtration.stream_space_single (proj_stoch_proc geom_proc n) r"
        have "A  sets (stream_space borel)"  using infinite_cts_filtration.stream_space_single_set
          unfolding A_def using badapt icf stk_price asm by blast
        moreover have "range (proj_stoch_proc geom_proc n)  A = {r}"
          unfolding A_def using badapt icf stk_price infinite_cts_filtration.stream_space_single_preimage asm by blast
        ultimately show "Asets (stream_space borel). range (proj_stoch_proc geom_proc n)  A = {r}" by auto
      qed
      show "y z. proj_stoch_proc geom_proc n y = proj_stoch_proc geom_proc n z  y !! n = z !! n 
        prices Mkt stk (Suc n) y = prices Mkt stk (Suc n) z"
      proof (intro allI impI)
        fix y z
        assume "proj_stoch_proc geom_proc n y = proj_stoch_proc geom_proc n z  y !! n = z !! n"
        hence "geom_proc n y = geom_proc n z" using proj_stoch_proc_component(2)[of n n]
        proof -
          show ?thesis
            by (metis w f. n  n  proj_stoch_proc f n w !! n = f n w proj_stoch_proc geom_proc n y = proj_stoch_proc geom_proc n z  y !! n = z !! n order_refl)
        qed
        hence "geom_proc (Suc n) y = geom_proc (Suc n) z" using geometric_process
          by (simp add: proj_stoch_proc geom_proc n y = proj_stoch_proc geom_proc n z  y !! n = z !! n)
        thus "prices Mkt stk (Suc n) y = prices Mkt stk (Suc n) z" using stk_price by simp
      qed
      show "0 < q" and "q < 1" using assms by auto
    qed
    moreover have "w. q * prices Mkt stk (Suc n) (pseudo_proj_True n w) + (1 - q) * prices Mkt stk (Suc n) (pseudo_proj_False n w) =
      (q * u + (1 - q) * d) * prices Mkt stk n w"
    proof
      fix w
      have "q * prices Mkt stk (Suc n) (pseudo_proj_True n w) + (1 - q) * prices Mkt stk (Suc n) (pseudo_proj_False n w) =
        q * geom_proc (Suc n) (pseudo_proj_True n w) + (1-q) * geom_proc (Suc n) (pseudo_proj_False n w)"
        by (simp add:stk_price)
      also have "... = q * u * geom_proc n (pseudo_proj_True n w) + (1-q) * geom_proc (Suc n) (pseudo_proj_False n w)"
        using geometric_process unfolding pseudo_proj_True_def by simp
      also have "... = q * u * geom_proc n w + (1-q) * geom_proc (Suc n) (pseudo_proj_False n w)"
        by (metis geom_rand_walk_pseudo_proj_True o_apply)
      also have "... = q * u * geom_proc n w + (1-q) * d * geom_proc n (pseudo_proj_False n w)"
        using geometric_process unfolding pseudo_proj_False_def by simp
      also have "... = q * u * geom_proc n w + (1-q) * d * geom_proc n w"
        by (metis geom_rand_walk_pseudo_proj_False o_apply)
      also have "... = (q * u + (1 - q) * d) * geom_proc n w" by (simp add: distrib_right)
      finally show "q * prices Mkt stk (Suc n) (pseudo_proj_True n w) + (1 - q) * prices Mkt stk (Suc n) (pseudo_proj_False n w) =
        (q * u + (1 - q) * d) * prices Mkt stk n w" using stk_price by simp
    qed
    ultimately show "AEeq N (real_cond_exp N (fct_gen_subalgebra N (stream_space borel)
                                  (proj_stoch_proc geom_proc n))
                                  ((prices Mkt stk) (Suc n)))
                    (λw. (q * u + (1 - q) * d) * prices Mkt stk n w)" by simp
  qed
  ultimately show ?thesis by auto
qed



lemma (in CRR_market) risky_asset_martingale_only_if:
  assumes "N = bernoulli_stream q"
  and "0 < q"
  and "q < 1"
  and  "martingale N G (discounted_value r (prices Mkt stk))"
shows "q = (1 + r - d) / (u - d)"
proof -
  have "AE w in N. real_cond_exp N (G 0)
       (discounted_value r (prices Mkt stk) (Suc 0)) w =  discounted_value r (prices Mkt stk) 0 w" using assms
    unfolding martingale_def by simp
  hence "AE w in N. real_cond_exp N (G 0)
       (discounted_value r (prices Mkt stk) (Suc 0)) w =  prices Mkt stk 0 w" by (simp add: discounted_init)
  moreover have "AE w in N. real_cond_exp N (G 0) (discounted_value r (prices Mkt stk) (Suc 0)) w =
    discounted_value r (λm w. (q * u + (1 - q) * d) * prices Mkt stk 0 w) (Suc 0) w"
    using assms real_cond_exp_discount_stock by simp
  ultimately have "AE w in N. discounted_value r (λm w. (q * u + (1 - q) * d) * prices Mkt stk 0 w) (Suc 0) w =
    prices Mkt stk 0 w" by auto
  hence "AE w in N. discounted_value r (λm w. (q * u + (1 - q) * d) * init) (Suc 0) w =
    (λw. init) w" using stk_price geometric_process by simp
  hence "AE w in N. discount_factor r (Suc 0) w * (q * u + (1 - q) * d) * init =
    (λw. init) w" unfolding discounted_value_def by simp
  hence "AE w in N. (1+r) * discount_factor r (Suc 0) w * (q * u + (1 - q) * d) * init =
    (1+r) * (λw. init) w" by auto
  hence prev: "AE w in N. discount_factor r 0 w * (q * u + (1 - q) * d) * init =
    (1+r) * (λw. init) w" using discount_factor_times_rfr[of r 0] acceptable_rate
  proof -
    have "s. (1 + r) * discount_factor r (Suc 0) (s::bool stream) = discount_factor r 0 s"
    by (metis (no_types) w. - 1 < r  (1 + r) * discount_factor r (Suc 0) w = discount_factor r 0 w acceptable_rate)
    then show ?thesis
    using AEeq N (λw. (1 + r) * discount_factor r (Suc 0) w * (q * u + (1 - q) * d) * init) (λw. (1 + r) * init) by presburger
  qed
  hence "w. (λw. discount_factor r 0 w * (q * u + (1 - q) * d) * init) w =
    (λw. (1+r) * init) w"
  proof -
    have "(λw. discount_factor r 0 w *  (q * u + (1 - q) * d) * init)
       borel_measurable (infinite_coin_toss_space.nat_filtration N 0)"
    proof (rule borel_measurable_times)+
      show "(λx. init)  borel_measurable (infinite_coin_toss_space.nat_filtration N 0)" by simp
      show "(λx. q * u + (1 - q) * d)  borel_measurable (infinite_coin_toss_space.nat_filtration N 0)" by simp
      show "discount_factor r 0  borel_measurable (infinite_coin_toss_space.nat_filtration N 0)"
        using discount_factor_nonrandom[of r 0 "infinite_coin_toss_space.nat_filtration N 0"] by simp
    qed
    moreover have "(λw. (1 + r) * init)  borel_measurable (infinite_coin_toss_space.nat_filtration N 0)" by simp
    moreover have "infinite_coin_toss_space q N" using assms by (simp add: infinite_coin_toss_space_def)
    ultimately show ?thesis
      using  prev infinite_coin_toss_space.nat_filtration_AE_eq[of q N
        "(λw. discount_factor r 0 w * (q * u + (1 - q) * d) * init)" "(λw. (1 + r) * init)" 0] assms
      by (simp add: discount_factor_init)
  qed
  hence "(q * u + (1 - q) * d) * init = (1+r) * init" by (simp add: discount_factor_init)
  hence "q * u + (1 - q) * d = 1+r" using S0_positive by simp
  hence "q * u + d - q * d = 1+r" by (simp add: left_diff_distrib)
  hence "q * (u - d) = 1 + r - d"
    by (metis (no_types, opaque_lifting) add.commute add.left_commute add_diff_cancel_left' add_uminus_conv_diff left_diff_distrib mult.commute)
  thus "q = (1 + r - d) / (u - d)" using down_lt_up
    by (metis add.commute add.right_neutral diff_add_cancel nonzero_eq_divide_eq order_less_irrefl)
qed



locale CRR_market_viable = CRR_market +
  assumes CRR_viable: "viable_market Mkt"


lemma (in CRR_market_viable) real_cond_exp_discount_stock_q_const:
  assumes "N = bernoulli_stream q"
and "q = (1+r-d) / (u-d)"
shows "AE w in N. real_cond_exp N (G n)
   (discounted_value r (prices Mkt stk) (Suc n)) w =
                  discounted_value r (prices Mkt stk) n w"
proof -
  have qlt: "0 < q" and qgt: "q < 1" using assms gt_param lt_param CRR_viable by auto
  have "AE w in N. real_cond_exp N (G n) (discounted_value r (prices Mkt stk) (Suc n)) w =
                  discounted_value r (λm w. (q * u + (1 - q) * d) * prices Mkt stk n w) (Suc n) w"
    using assms real_cond_exp_discount_stock[of N q] qlt qgt by simp
  moreover have "w. (q * u + (1 - q) * d) * prices Mkt stk n w =
    (1+r) * prices Mkt stk n w" using risk_neutral_param assms CRR_viable
      by (simp add: mult.commute)
  ultimately have "AE w in N. real_cond_exp N (G n) (discounted_value r (prices Mkt stk) (Suc n)) w =
                  discounted_value r (λm w. (1+r) * prices Mkt stk n w) (Suc n) w" by simp
  moreover have "w space N. discounted_value r (λm w. (1+r) * prices Mkt stk n w) (Suc n) w =
                     discounted_value r (λm w. prices Mkt stk n w) n w"
    using  acceptable_rate by (simp add:discounted_mult_times_rfr)
  moreover hence "w space N. discounted_value r (λm w. (1+r) * prices Mkt stk n w) (Suc n) w =
                     discounted_value r (prices Mkt stk) n w"
    using  acceptable_rate by (simp add:discounted_value_def)
  ultimately show "AE w in N. real_cond_exp N (G n) (discounted_value r (prices Mkt stk) (Suc n)) w =
                    discounted_value r (prices Mkt stk) n w" by simp
qed


lemma (in CRR_market_viable) risky_asset_martingale_if:
  assumes "N = bernoulli_stream q"
  and "q = (1 + r - d) / (u - d)"
shows "martingale N G (discounted_value r (prices Mkt stk))"
proof (rule disc_martingale_charact)
  have qlt: "0 < q" and qgt: "q < 1" using assms gt_param lt_param CRR_viable by auto
  show "n. integrable N (discounted_value r (prices Mkt stk) n)"
  proof
    fix n
    show "integrable N (discounted_value r (prices Mkt stk) n)"
    proof (rule discounted_integrable)
      show "space N = space M" using assms by (simp add: bernoulli bernoulli_stream_space)
      show "integrable N (prices Mkt stk n)"
      proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
        show "infinite_coin_toss_space q N" using assms qlt qgt
          by (simp add: infinite_coin_toss_space_def)
        show "prices Mkt stk n  borel_measurable (infinite_coin_toss_space.nat_filtration N n)"
          using geom_rand_walk_borel_adapted stk_price  nat_filtration_from_eq_sets unfolding adapt_stoch_proc_def
          by (metis infinite_coin_toss_space q N borel_measurable_integrable geom_proc_integrable geom_rand_walk_pseudo_proj_True
              infinite_coin_toss_space.nat_filtration_borel_measurable_characterization infinite_coin_toss_space_def)
      qed
      show "-1 < r" using acceptable_rate by simp
    qed
  qed
  show "filtration N G" using qlt qgt by (simp add: bernoulli_gen_filtration assms)
  show "n. sigma_finite_subalgebra N (G n)" using qlt qgt by (simp add: assms bernoulli_sigma_finite)
  show "m. discounted_value r (prices Mkt stk) m  borel_measurable (G m)"
  proof
    fix m
    have "discounted_value r (λma. prices Mkt stk m) m  borel_measurable (G m)"
    proof (rule discounted_measurable)
      show "prices Mkt stk m  borel_measurable (G m)" using stock_price_borel_measurable
        unfolding adapt_stoch_proc_def by simp
    qed
    thus "discounted_value r (prices Mkt stk) m  borel_measurable (G m)"
      by (metis (mono_tags, lifting) discounted_value_def measurable_cong)
  qed
  show "n. AE w in N. real_cond_exp N (G n)
       (discounted_value r (prices Mkt stk) (Suc n)) w = discounted_value r (prices Mkt stk) n w"
  proof
    fix n
    show "AE w in N. real_cond_exp N (G n)
       (discounted_value r (prices Mkt stk) (Suc n)) w = discounted_value r (prices Mkt stk) n w"
      using assms real_cond_exp_discount_stock_q_const by simp
  qed
qed


lemma (in CRR_market_viable) risk_neutral_iff':
  assumes "N = bernoulli_stream q"
and "0  q"
and "q  1"
and "filt_equiv nat_filtration M N"
shows "rfr_disc_equity_market.risk_neutral_prob G Mkt r N  q= (1 + r - d) / (u - d)"
proof
  have "0 < q" and "q < 1" using assms filt_equiv_sgt filt_equiv_slt psgt pslt by auto note qprops = this
  have dem: "rfr_disc_equity_market M G Mkt r risk_free_asset"  by unfold_locales
  {
    assume "rfr_disc_equity_market.risk_neutral_prob G Mkt r N"
    hence "(prob_space N)  ( asset  stocks Mkt. martingale N G (discounted_value r (prices Mkt asset)))"
      using rfr_disc_equity_market.risk_neutral_prob_def[of M G Mkt] dem  by simp
    hence "martingale N G (discounted_value r (prices Mkt stk))" using stocks by simp
    thus "q = (1 + r - d) / (u - d)" using assms risky_asset_martingale_only_if[of N q] qprops by simp
  }
  {
    assume "q = (1 + r - d) / (u - d)"
    hence "martingale N G (discounted_value r (prices Mkt stk))" using risky_asset_martingale_if[of N q] assms by simp
    moreover have "martingale N G (discounted_value r (prices Mkt risk_free_asset))" using risk_free_asset_martingale
      assms qprops by simp
    ultimately show "rfr_disc_equity_market.risk_neutral_prob G Mkt r N" using stocks
      using assms(1) bernoulli_stream_def dem prob_space.prob_space_stream_space prob_space_measure_pmf
        rfr_disc_equity_market.risk_neutral_prob_def by fastforce
  }
qed

lemma (in CRR_market_viable) risk_neutral_iff:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "rfr_disc_equity_market.risk_neutral_prob G Mkt r N  q= (1 + r - d) / (u - d)"
  using bernoulli_stream_equiv assms risk_neutral_iff' psgt pslt by auto

subsection ‹Existence of a replicating portfolio›




fun (in CRR_market) rn_rev_price where
  "rn_rev_price N der matur 0 w = der w" |
  "rn_rev_price N der matur (Suc n) w = discount_factor r (Suc 0) w *
                                  expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n)) (rn_rev_price N der matur n) w"






lemma (in CRR_market) stock_filtration_eq:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "G n = stoch_proc_filt N geom_proc borel n"
proof -
  have "G n= stoch_proc_filt M geom_proc borel n" using stock_filtration by simp
  also have "... = stoch_proc_filt N geom_proc borel n"
  proof (rule stoch_proc_filt_filt_equiv)
    show "filt_equiv nat_filtration M N" using assms bernoulli_stream_equiv psgt pslt by simp
  qed
  finally show ?thesis .
qed



lemma (in CRR_market) real_exp_eq:
  assumes "der borel_measurable (G matur)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "real_cond_exp N (stoch_proc_filt N geom_proc borel n) der w =
      expl_cond_expect N (proj_stoch_proc geom_proc n) der w"
proof -
  have "der  borel_measurable (nat_filtration matur)" using assms
      using geom_rand_walk_borel_adapted measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
  have "integrable N der"
  proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
    show "infinite_coin_toss_space q N" using assms
      by (simp add: infinite_coin_toss_space_def)
    show "der  borel_measurable (infinite_coin_toss_space.nat_filtration N matur)"
      by (metis der  borel_measurable (nat_filtration matur) infinite_coin_toss_space q N
          assms(2) assms(3) assms(4) infinite_coin_toss_space.nat_filtration_space measurable_from_subalg
          nat_filtration_from_eq_sets nat_filtration_space subalgebra_def subset_eq)
  qed
  show "real_cond_exp N (stoch_proc_filt N geom_proc borel n) der w =
    expl_cond_expect N (proj_stoch_proc geom_proc n) der w"
  proof (rule bernoulli_cond_exp)
    show "N = bernoulli_stream q" "0 < q" "q < 1" using assms by auto
    show "integrable N der" using integrable N der .
  qed
qed

lemma (in CRR_market) rn_rev_price_rev_borel_adapt:
assumes "cash_flow  borel_measurable (G matur)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "(n  matur)  (rn_rev_price N cash_flow matur n)  borel_measurable (G (matur - n))"
proof (induct n)
case 0 thus ?case using assms by simp
next
  case (Suc n)
  have "rn_rev_price N cash_flow matur (Suc n) =
      (λw. discount_factor r (Suc 0) w *
        (expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n)) (rn_rev_price N cash_flow matur n)) w)"
    using rn_rev_price.simps(2) by blast
  also have "...  borel_measurable (G (matur - Suc n))"
  proof (rule borel_measurable_times)
    show "discount_factor r (Suc 0)  borel_measurable (G (matur - Suc n))" by (simp add:discount_factor_borel_measurable)
    show "expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n)) (rn_rev_price N cash_flow matur n)
       borel_measurable (G (matur - Suc n))" using assms by (simp add: bernoulli_expl_cond_expect_adapt)
  qed
  finally show "rn_rev_price N cash_flow matur (Suc n)  borel_measurable (G (matur - Suc n))" .
qed

lemma (in infinite_coin_toss_space) bernoulli_discounted_integrable:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
  and "der  borel_measurable (nat_filtration n)"
and "-1 < r"
  shows "integrable N (discounted_value r (λm. der) m)"
proof -
  have "prob_space N" using assms
    by (simp add: bernoulli bernoulli_stream_def prob_space.prob_space_stream_space prob_space_measure_pmf)
  have "integrable N der"
  proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
    show "infinite_coin_toss_space q N" using assms
      by (simp add: infinite_coin_toss_space_def)
    show "der  borel_measurable (infinite_coin_toss_space.nat_filtration N n)"
      using assms filt_equiv_filtration
      by (simp add: assms(1) measurable_def nat_filtration_from_eq_sets nat_filtration_space)
  qed
  thus ?thesis using discounted_integrable assms
    by (metis prob_space N prob_space.discounted_integrable)
qed



lemma (in CRR_market) rn_rev_expl_cond_expect:
  assumes "der borel_measurable (G matur)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
shows "n  matur  rn_rev_price N der matur n w =
  expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n) w"
proof (induct n arbitrary: w)
  case 0
  have "der  borel_measurable (nat_filtration matur)" using assms
      using geom_rand_walk_borel_adapted measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
  have "integrable N der"
  proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
    show "infinite_coin_toss_space q N" using assms
      by (simp add: infinite_coin_toss_space_def)
    show "der  borel_measurable (infinite_coin_toss_space.nat_filtration N matur)"
      by (metis der  borel_measurable (nat_filtration matur) infinite_coin_toss_space q N
          assms(2) assms(3) assms(4) infinite_coin_toss_space.nat_filtration_space measurable_from_subalg
          nat_filtration_from_eq_sets nat_filtration_space subalgebra_def subset_eq)
  qed
  have "rn_rev_price N der matur 0 w = der w" by simp
  also have "... = expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0) w"
  proof (rule nat_filtration_AE_eq)
    show "der  borel_measurable (nat_filtration matur)" using der  borel_measurable (nat_filtration matur) .
    have "(discounted_value r (λm. der) 0) = der" unfolding discounted_value_def discount_factor_def by simp
    moreover have "AEeq N (real_cond_exp N (G matur) der) der"
    proof (rule sigma_finite_subalgebra.real_cond_exp_F_meas)
      show "der  borel_measurable (G matur)" using assms by simp
      show "integrable N der" using integrable N der .
      show "sigma_finite_subalgebra N (G matur)" using bernoulli_sigma_finite
        using assms by simp
    qed
    moreover have "w. real_cond_exp N (stoch_proc_filt N geom_proc borel matur) der w =
      expl_cond_expect N (proj_stoch_proc geom_proc matur) der w" using assms real_exp_eq by simp
    ultimately have eqn: "AEeq N der (expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0))"
      using stock_filtration_eq assms by auto
    have "stoch_proc_filt M geom_proc borel matur = stoch_proc_filt N geom_proc borel matur"
      using  bernoulli_stream_equiv[of N q] assms psgt pslt by (simp add: stoch_proc_filt_filt_equiv)
    also have "stoch_proc_filt N geom_proc borel matur =
      fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc matur)"
      using assms geom_proc_stoch_proc_filt by simp
    finally have "stoch_proc_filt M geom_proc borel matur =
      fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc matur)" .
    moreover have "expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0)
       borel_measurable (fct_gen_subalgebra N (stream_space borel) (proj_stoch_proc geom_proc matur))"
    proof (rule expl_cond_exp_borel)
      show "proj_stoch_proc geom_proc matur  space N  space (stream_space borel)"
        using assms proj_stoch_proc_geom_rng by (simp add: measurable_def)
      show "disc_fct (proj_stoch_proc geom_proc matur)" using proj_stoch_proc_geom_disc_fct by simp
      show "rrange (proj_stoch_proc geom_proc matur)  space (stream_space borel).
        Asets (stream_space borel). range (proj_stoch_proc geom_proc matur)  A = {r}"
        using proj_stoch_proc_geom_open_set by simp
    qed
    ultimately show ebm: "expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0)
       borel_measurable (nat_filtration matur)"
      by (metis geom_rand_walk_borel_adapted measurable_from_subalg stoch_proc_subalg_nat_filt)
    show "AEeq M der (expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0))"
    proof (rule filt_equiv_borel_AE_eq_iff[THEN iffD2])
      show "filt_equiv nat_filtration M N" using assms bernoulli_stream_equiv psgt pslt by simp
      show "der  borel_measurable (nat_filtration matur)" using der  borel_measurable (nat_filtration matur) .
      show "AEeq N der (expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0))"
        using eqn .
      show "expl_cond_expect N (proj_stoch_proc geom_proc matur) (discounted_value r (λm. der) 0)
         borel_measurable (nat_filtration matur)" using ebm .
      show "prob_space N" using assms by (simp add: bernoulli_stream_def
            prob_space.prob_space_stream_space prob_space_measure_pmf)
      show "prob_space M" by (simp add: bernoulli bernoulli_stream_def
            prob_space.prob_space_stream_space prob_space_measure_pmf)
    qed
    show "0 < p" "p < 1" using psgt pslt by auto
  qed
  also have "... = expl_cond_expect N (proj_stoch_proc geom_proc (matur - 0)) (discounted_value r (λm. der) 0) w"
    by simp
  finally show "rn_rev_price N der matur 0 w =
    expl_cond_expect N (proj_stoch_proc geom_proc (matur - 0)) (discounted_value r (λm. der) 0) w" .
next
  case (Suc n)
  have "rn_rev_price N der matur (Suc n) w = discount_factor r (Suc 0) w *
          expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n)) (rn_rev_price N der matur n) w" by simp
  also have "... = discount_factor r (Suc 0) w *
    real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (rn_rev_price N der matur n) w"
  proof -
    have "expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n)) (rn_rev_price N der matur n) w =
     real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (rn_rev_price N der matur n) w"
    proof (rule real_exp_eq[symmetric])
      show "rn_rev_price N der matur n  borel_measurable (G (matur - n))"
        using assms rn_rev_price_rev_borel_adapt Suc by simp
      show "N = bernoulli_stream q" "0 < q" "q < 1" using assms by auto
    qed
    thus ?thesis by simp
  qed
  also have "... = discount_factor r (Suc 0) w *
    real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
    (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)) w"
  proof -
    have "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (rn_rev_price N der matur n) w =
      real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
    (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)) w"
    proof (rule infinite_coin_toss_space.nat_filtration_AE_eq)
      show "AEeq N (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (rn_rev_price N der matur n))
        (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
        (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)))"
      proof (rule sigma_finite_subalgebra.real_cond_exp_cong)
        show "sigma_finite_subalgebra N (stoch_proc_filt N geom_proc borel (matur - Suc n))"
          using assms(2) assms(3) assms(4) bernoulli_sigma_finite stock_filtration_eq by auto
        show "rn_rev_price N der matur n  borel_measurable N"
        proof -
          have "rn_rev_price N der matur n  borel_measurable (G (matur - n))"
            by (metis (full_types) Suc.prems Suc_leD assms(1) assms(2) assms(3) assms(4) rn_rev_price_rev_borel_adapt)
          then show ?thesis
            by (metis (no_types) assms(2) bernoulli bernoulli_stream_def filtration_measurable measurable_cong_sets sets_measure_pmf sets_stream_space_cong)
        qed
        show "expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)  borel_measurable N"
          using Suc.hyps Suc.prems Suc_leD rn_rev_price N der matur n  borel_measurable N by presburger
        show "AEeq N (rn_rev_price N der matur n)
          (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n))" using Suc by auto
      qed
      show "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (rn_rev_price N der matur n)
         borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
        by (metis assms(2) assms(3) assms(4) borel_measurable_cond_exp infinite_coin_toss_space.intro
            infinite_coin_toss_space.stoch_proc_subalg_nat_filt linear measurable_from_subalg not_less
            prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      show "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
         (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n))
         borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
        by (metis assms(2) assms(3) assms(4) borel_measurable_cond_exp infinite_coin_toss_space.intro
              infinite_coin_toss_space.stoch_proc_subalg_nat_filt linear measurable_from_subalg not_less
              prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      show "0 < q" "q < 1" using assms by auto
      show "infinite_coin_toss_space q N" using assms
        by (simp add: infinite_coin_toss_space_def)
    qed
    thus ?thesis by simp
  qed
  also have "... = discount_factor r (Suc 0) w *
  real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
   (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)) w"
  proof -
    have "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
      (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)) w =
      real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
      (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)) w"
    proof (rule infinite_coin_toss_space.nat_filtration_AE_eq)
      show "AEeq N (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
             (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)))
         (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
           (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)))"
      proof (rule sigma_finite_subalgebra.real_cond_exp_cong)
        show "sigma_finite_subalgebra N (stoch_proc_filt N geom_proc borel (matur - Suc n))"
          using assms(2) assms(3) assms(4) bernoulli_sigma_finite stock_filtration_eq by auto
        show "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)  borel_measurable N"
          by simp
        show "expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)  borel_measurable N"
          by (metis assms(2) assms(3) assms(4) bernoulli bernoulli_expl_cond_expect_adapt bernoulli_stream_def filtration_measurable
              measurable_cong_sets sets_measure_pmf sets_stream_space_cong)
        show "AEeq N (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n))
          (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n))"
        proof -
          have "discounted_value r (λm. der) n  borel_measurable (G matur)" using assms discounted_measurable[of der]
            by simp
          hence "w. (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n)) w =
            (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)) w"
            using real_exp_eq[of _ matur N q "matur-n"] assms by simp
          thus ?thesis by simp
        qed
      qed
      show "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
         (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n))
         borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
        by (metis assms(2) assms(3) assms(4) borel_measurable_cond_exp infinite_coin_toss_space.intro
              infinite_coin_toss_space.stoch_proc_subalg_nat_filt linear measurable_from_subalg not_less
              prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      show "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
         (expl_cond_expect N (proj_stoch_proc geom_proc (matur - n)) (discounted_value r (λm. der) n))
         borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
        by (metis assms(2) assms(3) assms(4) borel_measurable_cond_exp infinite_coin_toss_space.intro
              infinite_coin_toss_space.stoch_proc_subalg_nat_filt linear measurable_from_subalg not_less
              prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      show "0 < q" "q < 1" using assms by auto
      show "infinite_coin_toss_space q N" using assms
        by (simp add: infinite_coin_toss_space_def)
    qed
    thus ?thesis by simp
  qed
  also have "... = real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
    (discounted_value r (λm. der) (Suc n)) w"
  proof (rule infinite_coin_toss_space.nat_filtration_AE_eq)
    show "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (discounted_value r (λm. der) (Suc n))
       borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
        by (metis assms(2) assms(3) assms(4) borel_measurable_cond_exp infinite_coin_toss_space.intro
              infinite_coin_toss_space.stoch_proc_subalg_nat_filt linear measurable_from_subalg not_less
              prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      show "(λa. discount_factor r (Suc 0) a *
          real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
           (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)) a)
         borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
      proof -
        have "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
           (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n))
         borel_measurable (infinite_coin_toss_space.nat_filtration N (matur - Suc n))"
        by (metis assms(2) assms(3) assms(4) borel_measurable_cond_exp infinite_coin_toss_space.intro
              infinite_coin_toss_space.stoch_proc_subalg_nat_filt linear measurable_from_subalg not_less
              prob_grw.geom_rand_walk_borel_adapted prob_grw_axioms prob_grw_def)
      thus ?thesis using discounted_measurable[of "real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
        (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n))"]
        unfolding discounted_value_def by simp
    qed
    show "0 < q" "q < 1" using assms by auto
    show "infinite_coin_toss_space q N" using assms
      by (simp add: infinite_coin_toss_space_def)
    show "AEeq N (λw. discount_factor r (Suc 0) w *
                 real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
                  (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)) w)
     (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (discounted_value r (λm. der) (Suc n)))"
    proof-
      have "AEeq N
        (λw. discount_factor r (Suc 0) w *
                 real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
                  (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)) w)
        (λw. discount_factor r (Suc 0) w *
                 real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (discounted_value r (λm. der) n) w)"
      proof -
        have "AEeq N (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
                  (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - n)) (discounted_value r (λm. der) n)))
                (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (discounted_value r (λm. der) n))"
        proof (rule sigma_finite_subalgebra.real_cond_exp_nested_subalg)
          show "sigma_finite_subalgebra N (stoch_proc_filt N geom_proc borel (matur - Suc n))"
            using assms(2) assms(3) assms(4) bernoulli_sigma_finite stock_filtration_eq by auto
          show "subalgebra N (stoch_proc_filt N geom_proc borel (matur - n))"
            using assms(2) assms(3) assms(4) bernoulli_sigma_finite sigma_finite_subalgebra.subalg
              stock_filtration_eq by fastforce
          show "subalgebra (stoch_proc_filt N geom_proc borel (matur - n)) (stoch_proc_filt N geom_proc borel (matur - Suc n))"
          proof -
            have "init_triv_filt M (stoch_proc_filt M geom_proc borel)" using infinite_cts_filtration.stoch_proc_filt_triv_init
              using info_filtration stock_filtration by auto
            moreover have "matur - (Suc n)  matur - n" by simp
            ultimately show ?thesis unfolding init_triv_filt_def filtration_def
              using assms(2) assms(3) assms(4) stock_filtration stock_filtration_eq by auto
          qed
          show "integrable N (discounted_value r (λm. der) n) " using bernoulli_discounted_integrable[of N q der matur r n] acceptable_rate assms
            using geom_rand_walk_borel_adapted measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
        qed
        thus ?thesis  by auto
      qed
      moreover have "AEeq N
        (λw. discount_factor r (Suc 0) w *
         real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (discounted_value r (λm. der) n) w)
        (λw. discount_factor r (Suc 0) w * (discounted_value r
         (λm. real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) der) n) w)"
      proof -
        have "AEeq N (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) (discounted_value r (λm. der) n))
          (discounted_value r
         (λm. real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) der) n)"
        proof (rule prob_space.discounted_value_real_cond_exp)
          show "prob_space N" using assms
            by (simp add: bernoulli bernoulli_stream_def prob_space.prob_space_stream_space prob_space_measure_pmf)
          have "der  borel_measurable (nat_filtration matur)" using assms
            using geom_rand_walk_borel_adapted measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
          show "integrable N der"
          proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
            show "infinite_coin_toss_space q N" using assms
              by (simp add: infinite_coin_toss_space_def)
            show "der  borel_measurable (infinite_coin_toss_space.nat_filtration N matur)"
              by (metis der  borel_measurable (nat_filtration matur) infinite_coin_toss_space q N
                  assms(2) assms(3) assms(4) infinite_coin_toss_space.nat_filtration_space measurable_from_subalg
                  nat_filtration_from_eq_sets nat_filtration_space subalgebra_def subset_eq)
          qed
          show "-1 < r" using acceptable_rate .
          show "subalgebra N (stoch_proc_filt N geom_proc borel (matur - Suc n))"
            using assms(2) assms(3) assms(4) bernoulli_sigma_finite sigma_finite_subalgebra.subalg
              stock_filtration_eq by fastforce
        qed
        thus ?thesis  by auto
      qed
      moreover have "w. (λw. discount_factor r (Suc 0) w * (discounted_value r
         (λm. real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) der) n) w) w =
        (discounted_value r
         (λm. real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) der) (Suc n)) w"
        unfolding discounted_value_def discount_factor_def  by simp
      moreover have "AEeq N
        (real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n))
        (discounted_value r (λm. der) (Suc n)))
        (discounted_value r
        (λm. real_cond_exp N (stoch_proc_filt N geom_proc borel (matur - Suc n)) der) (Suc n))"
      proof (rule prob_space.discounted_value_real_cond_exp)
        show "prob_space N" using assms
            by (simp add: bernoulli bernoulli_stream_def prob_space.prob_space_stream_space prob_space_measure_pmf)
        have "der  borel_measurable (nat_filtration matur)" using assms
          using geom_rand_walk_borel_adapted measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
        show "integrable N der"
        proof (rule infinite_coin_toss_space.nat_filtration_borel_measurable_integrable)
          show "infinite_coin_toss_space q N" using assms
            by (simp add: infinite_coin_toss_space_def)
          show "der  borel_measurable (infinite_coin_toss_space.nat_filtration N matur)"
            by (metis der  borel_measurable (nat_filtration matur) infinite_coin_toss_space q N
                assms(2) assms(3) assms(4) infinite_coin_toss_space.nat_filtration_space measurable_from_subalg
                nat_filtration_from_eq_sets nat_filtration_space subalgebra_def subset_eq)
        qed
        show "-1 < r" using acceptable_rate .
        show "subalgebra N (stoch_proc_filt N geom_proc borel (matur - Suc n))"
          using assms(2) assms(3) assms(4) bernoulli_sigma_finite sigma_finite_subalgebra.subalg
            stock_filtration_eq by fastforce
      qed
      ultimately show ?thesis by auto
    qed
  qed
  also have "... = expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n))
    (discounted_value r (λm. der) (Suc n)) w"
  proof (rule real_exp_eq)
    show "discounted_value r (λm. der) (Suc n)  borel_measurable (G matur)" using assms discounted_measurable[of der]
      by simp
    show "N = bernoulli_stream q" "0 < q" "q < 1" using assms by auto
  qed
  finally show "rn_rev_price N der matur (Suc n) w =
    expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc n)) (discounted_value r (λm. der) (Suc n)) w" .
qed

definition (in CRR_market) rn_price where
"rn_price N der matur n w = expl_cond_expect N (proj_stoch_proc geom_proc n) (discounted_value r (λm. der) (matur - n)) w"


definition (in CRR_market) rn_price_ind where
"rn_price_ind N der matur n w = rn_rev_price N der matur (matur - n) w"

lemma (in CRR_market) rn_price_eq:
  assumes "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
and "der  borel_measurable (G matur)"
and "n  matur"
shows "rn_price N der matur n w = rn_price_ind N der matur n w" using rn_rev_expl_cond_expect
  unfolding rn_price_def rn_price_ind_def
  by (simp add: assms)


lemma (in CRR_market) geom_proc_filt_info:
  fixes f::"bool stream  'b::{t0_space}"
  assumes "f  borel_measurable (G n)"
  shows "f w = f (pseudo_proj_True n w)"
proof -
  have "subalgebra (nat_filtration n) (G n)" using stoch_proc_subalg_nat_filt[of geom_proc n] geometric_process
    stock_filtration geom_rand_walk_borel_adapted by simp
  hence "f borel_measurable (nat_filtration n)" using assms by (simp add: measurable_from_subalg)
  thus ?thesis using nat_filtration_info[of f n] by (metis comp_apply)
qed

lemma (in CRR_market) geom_proc_filt_info':
  fixes f::"bool stream  'b::{t0_space}"
  assumes "f  borel_measurable (G n)"
  shows "f w = f (pseudo_proj_False n w)"
proof -
  have "subalgebra (nat_filtration n) (G n)" using stoch_proc_subalg_nat_filt[of geom_proc n] geometric_process
    stock_filtration geom_rand_walk_borel_adapted by simp
  hence "f borel_measurable (nat_filtration n)" using assms by (simp add: measurable_from_subalg)
  thus ?thesis using nat_filtration_info'[of f n] by (metis comp_apply)
qed




lemma (in CRR_market) rn_price_borel_adapt:
assumes "cash_flow  borel_measurable (G matur)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
and "n  matur"
shows "(rn_price N cash_flow matur n)  borel_measurable (G n)"
proof -
  show "(rn_price N cash_flow matur n)  borel_measurable (G n)"
    using assms rn_rev_price_rev_borel_adapt[of cash_flow matur N q "matur - n"] rn_price_eq rn_price_ind_def
    by (smt add.right_neutral cancel_comm_monoid_add_class.diff_cancel diff_commute diff_le_self
        increasing_measurable_info measurable_cong nat_le_linear ordered_cancel_comm_monoid_diff_class.add_diff_inverse)
qed


definition (in CRR_market) delta_price where
  "delta_price N cash_flow T =
    (λ n w. if (Suc n  T)
      then (rn_price N cash_flow T (Suc n) (pseudo_proj_True n w) - rn_price N cash_flow T (Suc n) (pseudo_proj_False n w))/
        (geom_proc (Suc n) (spick w n True) - geom_proc (Suc n) (spick w n False))
      else 0)"


lemma (in CRR_market) delta_price_eq:
  assumes "Suc n  T"
  shows "delta_price N cash_flow T n w = (rn_price N cash_flow T (Suc n) (spick w n True) - rn_price N cash_flow T (Suc n) (spick w n False))/
    ((geom_proc n w) * (u - d))"
proof -
  have "(geom_proc (Suc n) (spick w n True) - geom_proc (Suc n) (spick w n False)) = geom_proc n w * (u - d)"
    by (simp add: geom_rand_walk_diff_induct)
  then show ?thesis unfolding delta_price_def using assms spick_eq_pseudo_proj_True spick_eq_pseudo_proj_False by simp
qed



lemma (in CRR_market) geom_proc_spick:
  shows "geom_proc (Suc n) (spick w n x)  = (if x then u else d) * geom_proc n w"
proof -
  have "geom_proc (Suc n) (spick w n x)  = geom_rand_walk u d init (Suc n) (spick w n x)" using geometric_process by simp
  also have "... = (case (spick w n x) !! n of True  u | False  d) * geom_rand_walk u d init n (spick w n x)"
    by simp
  also have "... = (case x of True  u | False  d) * geom_rand_walk u d init n (spick w n x)"
    unfolding spick_def by simp
  also have "... = (if x then u else d) * geom_rand_walk u d init n (spick w n x)" by simp
  also have "... = (if x then u else d) * geom_rand_walk u d init n w"
    by (metis comp_def geom_rand_walk_pseudo_proj_True geometric_process pseudo_proj_True_stake_image spickI)
  finally show ?thesis using geometric_process by simp
qed


lemma (in CRR_market) spick_red_geom:
  shows "(λw. spick w n x)  measurable (fct_gen_subalgebra M borel (geom_proc n)) (fct_gen_subalgebra M borel (geom_proc (Suc n)))"
  unfolding measurable_def
proof (intro CollectI conjI)
  show "(λw. spick w n x)
     space (fct_gen_subalgebra M borel (geom_proc n))  space (fct_gen_subalgebra M borel (geom_proc (Suc n)))"
    by (simp add: bernoulli bernoulli_stream_space fct_gen_subalgebra_space)
  show "ysets (fct_gen_subalgebra M borel (geom_proc (Suc n))).
       (λw. spick w n x) -` y  space (fct_gen_subalgebra M borel (geom_proc n))
        sets (fct_gen_subalgebra M borel (geom_proc n))"
  proof
    fix A
    assume A: "A  sets (fct_gen_subalgebra M borel (geom_proc (Suc n)))"
    show "(λw. spick w n x) -` A  space (fct_gen_subalgebra M borel (geom_proc n)) 
    sets (fct_gen_subalgebra M borel (geom_proc n))"
    proof -
      define sp where "sp = (λw. spick w n x)"
      have "A  {(geom_proc (Suc n)) -` B  space M |B. B  sets borel}" using A
        by (simp add:fct_gen_subalgebra_sigma_sets)
      from this obtain C where "C sets borel" and "A = (geom_proc (Suc n)) -`C  space M" by auto
      hence "A = (geom_proc (Suc n)) -`C" using bernoulli bernoulli_stream_space by simp
      hence "sp -`A = sp -` (geom_proc (Suc n)) -`C" by simp
      also have "... = (geom_proc (Suc n)  sp) -` C" by auto
      also have "... = (λw. (if x then u else d) * geom_proc n w) -` C" using geom_proc_spick
        sp_def by auto
      also have "...  sets (fct_gen_subalgebra M borel (geom_proc n))"
      proof (cases x)
        case True
        hence "(λw. (if x then u else d) * geom_proc n w) -` C = (λw. u * geom_proc n w) -` C" by simp
        moreover have "(λw. u * geom_proc n w)  borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
        proof -
          have "geom_proc n borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
            using fct_gen_subalgebra_fct_measurable
            by (metis (no_types, lifting) geom_rand_walk_borel_measurable measurable_def mem_Collect_eq)
          thus ?thesis by simp
        qed
        ultimately show ?thesis using C sets borel
          by (metis bernoulli bernoulli_stream_preimage fct_gen_subalgebra_space measurable_sets)
      next
        case False
        hence "(λw. (if x then u else d) * geom_proc n w) -` C = (λw. d * geom_proc n w) -` C" by simp
        moreover have "(λw. d * geom_proc n w)  borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
        proof -
          have "geom_proc n borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
            using fct_gen_subalgebra_fct_measurable
            by (metis (no_types, lifting) geom_rand_walk_borel_measurable measurable_def mem_Collect_eq)
          thus ?thesis by simp
        qed
        ultimately show ?thesis using C sets borel
          by (metis bernoulli bernoulli_stream_preimage fct_gen_subalgebra_space measurable_sets)
      qed
      finally show ?thesis unfolding sp_def by (simp add: bernoulli bernoulli_stream_space fct_gen_subalgebra_space)
    qed
  qed
qed

lemma (in CRR_market) geom_spick_Suc:
  assumes "A  {(geom_proc (Suc n)) -` B |B. B  sets borel}"
  shows "(λw. spick w n x) -`A  {geom_proc n -`B | B. B sets borel}"
proof -
  have "sets (fct_gen_subalgebra M borel (geom_proc n)) = {geom_proc n -` B space M |B. B  sets borel}"
    by (simp add: fct_gen_subalgebra_sigma_sets)
  also have "... =  {geom_proc n -` B |B. B  sets borel}" using bernoulli bernoulli_stream_space by simp
  finally have sf: "sets (fct_gen_subalgebra M borel (geom_proc n)) = {geom_proc n -` B |B. B  sets borel}" .
  define sp where "sp = (λw. spick w n x)"
  from assms(1) obtain C where "C sets borel" and "A = (geom_proc (Suc n)) -`C" by auto
  hence "A = (geom_proc (Suc n)) -`C" using bernoulli bernoulli_stream_space by simp
  hence "sp -`A = sp -` (geom_proc (Suc n)) -`C" by simp
  also have "... = (geom_proc (Suc n)  sp) -` C" by auto
  also have "... = (λw. (if x then u else d) * geom_proc n w) -` C" using geom_proc_spick
    sp_def by auto
  also have "...  {geom_proc n -`B | B. B sets borel}"
  proof (cases x)
    case True
    hence "(λw. (if x then u else d) * geom_proc n w) -` C = (λw. u * geom_proc n w) -` C" by simp
    moreover have "(λw. u * geom_proc n w)  borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
    proof -
      have "geom_proc n borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
        using fct_gen_subalgebra_fct_measurable
        by (metis (no_types, lifting) geom_rand_walk_borel_measurable measurable_def mem_Collect_eq)
      thus ?thesis by simp
    qed
    ultimately show ?thesis using C sets borel sf
      by (simp add: bernoulli bernoulli_stream_preimage fct_gen_subalgebra_space in_borel_measurable_borel)
  next
    case False
    hence "(λw. (if x then u else d) * geom_proc n w) -` C = (λw. d * geom_proc n w) -` C" by simp
    moreover have "(λw. d * geom_proc n w)  borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
    proof -
      have "geom_proc n borel_measurable (fct_gen_subalgebra M borel (geom_proc n))"
        using fct_gen_subalgebra_fct_measurable
        by (metis (no_types, lifting) geom_rand_walk_borel_measurable measurable_def mem_Collect_eq)
      thus ?thesis by simp
    qed
    ultimately show ?thesis using C sets borel sf
      by (simp add: bernoulli bernoulli_stream_preimage fct_gen_subalgebra_space in_borel_measurable_borel)
  qed
  finally show ?thesis unfolding sp_def .
qed


lemma (in CRR_market) geom_spick_lt:
  assumes "m< n"
  shows "geom_proc m (spick w n x) = geom_proc m w"
proof -
  have "geom_proc m (spick w n x) = geom_proc m (pseudo_proj_True m (spick w n x))"
    using  geom_rand_walk_pseudo_proj_True by (metis comp_apply)
  also have "... = geom_proc m (pseudo_proj_True m w)" using assms
    by (metis less_imp_le_nat pseudo_proj_True_def pseudo_proj_True_prefix spickI)
  also have "... = geom_proc m w" using  geom_rand_walk_pseudo_proj_True by (metis comp_apply)
  finally show ?thesis .
qed

lemma (in CRR_market) geom_spick_eq:
  shows "geom_proc m (spick w m x) = geom_proc m w"
proof (cases x)
  case True
  have "geom_proc m (spick w m x) = geom_proc m (pseudo_proj_True m (spick w m x))"
    using  geom_rand_walk_pseudo_proj_True by (metis comp_apply)
  also have "... = geom_proc m (pseudo_proj_True m w)" using True
    by (metis pseudo_proj_True_def spickI)
  also have "... = geom_proc m w" using  geom_rand_walk_pseudo_proj_True by (metis comp_apply)
  finally show ?thesis .
next
  case False
  have "geom_proc m (spick w m x) = geom_proc m (pseudo_proj_False m (spick w m x))"
    using  geom_rand_walk_pseudo_proj_False by (metis comp_apply)
  also have "... = geom_proc m (pseudo_proj_False m w)" using False
    by (metis pseudo_proj_False_def spickI)
  also have "... = geom_proc m w" using  geom_rand_walk_pseudo_proj_False by (metis comp_apply)
  finally show ?thesis .
qed


lemma (in CRR_market) spick_red_geom_filt:
  shows "(λw. spick w n x)  measurable (G n) (G (Suc n))" unfolding measurable_def
proof (intro CollectI conjI)
  show "(λw. spick w n x)  space (G n)  space (G (Suc n))" using stock_filtration
    by (simp add: bernoulli bernoulli_stream_space stoch_proc_filt_space)
  show "ysets (G (Suc n)). (λw. spick w n x) -` y  space (G n)  sets (G n)"
  proof
    fix B
    assume "B sets (G (Suc n))"
    hence "B (sigma_sets (space M) ( i {m. m (Suc n)}. {(geom_proc i -`A)  (space M) | A. A sets borel }))"
      using stock_filtration stoch_proc_filt_sets geometric_process
    proof -
      have "n. sigma_sets (space M) (n{na. na  n}. {geom_proc n -` R  space M |R. R  sets borel}) = sets (G n)"
        by (simp add: geom_rand_walk_borel_measurable stoch_proc_filt_sets stock_filtration)
      then show ?thesis
        using B  sets (G (Suc n)) by blast
    qed
    hence "(λw. spick w n x) -` B  sets (G n)"
    proof (induct rule:sigma_sets.induct)
      {
        fix C
        assume "C  (i{m. m  Suc n}. {geom_proc i -` A  space M |A. A  sets borel})"
        hence "m  Suc n. C {geom_proc m -` A  space M |A. A  sets borel}" by auto
        from this obtain m where "m Suc n" and "C {geom_proc m -` A  space M |A. A  sets borel}" by auto
        note Cprops = this
        from this obtain D where "C = geom_proc m -` D space M" and "D sets borel" by auto
        hence "C = geom_proc m -`D" using bernoulli bernoulli_stream_space by simp
        have "C {geom_proc m -` A |A. A  sets borel}" using bernoulli bernoulli_stream_space Cprops by simp
        show "(λw. spick w n x) -` C  sets (G n)"
        proof (cases "m  n")
          case True
          have "(λw. spick w n x) -` C = (λw. spick w n x) -` geom_proc m -`D" using C = geom_proc m -`D by simp
          also have "... = (geom_proc m  (λw. spick w n x)) -`D" by auto
          also have "... = geom_proc m -`D" using geom_spick_lt geom_spick_eq mn
            using le_eq_less_or_eq by auto
          also have "...  sets (G n)" using stock_filtration geometric_process
            D sets borel
            by (metis (no_types, lifting) True adapt_stoch_proc_def bernoulli bernoulli_stream_preimage
                geom_rand_walk_borel_measurable increasing_measurable_info measurable_sets stoch_proc_filt_adapt
                stoch_proc_filt_space)
          finally show "(λw. spick w n x) -` C  sets (G n)" .
        next
          case False
          hence "m = Suc n" using m  Suc n by simp
          hence "(λw. spick w n x) -` C  {geom_proc n -` B |B. B  sets borel}"
            using C {geom_proc m -` A |A. A  sets borel} geom_spick_Suc by simp
          also have "...  sets (G n)"
          proof -
            have "{geom_proc n -` B |B. B  sets borel}  {geom_proc n -` B  space M |B. B  sets borel}"
              using bernoulli bernoulli_stream_space by simp
            also have "...  (i{m. m  n}. {geom_proc i -` A  space M |A. A  sets borel})"
               by auto
            also have "...   sigma_sets (space M) (i{m. m  n}. {geom_proc i -` A  space M |A. A  sets borel})"
              by (rule sigma_sets_superset_generator)
            also have "... = sets (G n)" using stock_filtration geometric_process
              stoch_proc_filt_sets[of n geom_proc M borel] geom_rand_walk_borel_measurable by blast
            finally show ?thesis .
          qed
          finally show ?thesis .
        qed
      }
      show "(λw. spick w n x) -` {}  sets (G n)" by simp
      {
        fix C
        assume "C  sigma_sets (space M) (i{m. m  Suc n}. {geom_proc i -` A  space M |A. A  sets borel})"
          and "(λw. spick w n x) -` C  sets (G n)"
        hence "(λw. spick w n x) -` (space M - C) = (λw. spick w n x) -` (space M) - (λw. spick w n x) -` C"
          by (simp add: vimage_Diff)
        also have "... = space M - (λw. spick w n x) -` C" using bernoulli bernoulli_stream_space by simp
        also have "...  sets (G n)" using (λw. spick w n x) -` C  sets (G n)
          by (metis algebra.compl_sets disc_filtr_def discrete_filtration sets.sigma_algebra_axioms
              sigma_algebra_def subalgebra_def)
        finally show "(λw. spick w n x) -` (space M - C)  sets (G n)" .
      }
      {
        fix C::"nat  bool stream set"
        assume "(i. C i  sigma_sets (space M) (i{m. m  Suc n}. {geom_proc i -` A  space M |A. A  sets borel}))"
          and "(i. (λw. spick w n x) -` C i  sets (G n))"
        hence "(λw. spick w n x) -` (C ` UNIV) = ( i UNIV. (λw. spick w n x) -` (C i))" by blast
        also have "...  sets (G n)" using i. (λw. spick w n x) -` C i  sets (G n) by simp
        finally show "(λw. spick w n x) -` (C ` UNIV)  sets (G n)" .
      }
    qed
    thus "(λw. spick w n x) -` B  space (G n)  sets (G n)" using stock_filtration stoch_proc_filt_space
      bernoulli bernoulli_stream_space by simp
  qed
qed

lemma (in CRR_market) delta_price_adapted:
   fixes cash_flow::"bool stream  real"
   assumes "cash_flow  borel_measurable (G T)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
  shows "borel_adapt_stoch_proc G (delta_price N cash_flow T)"
unfolding adapt_stoch_proc_def
proof
  fix n
  show "delta_price N cash_flow T n  borel_measurable (G n)"
  proof (cases "Suc n  T")
    case True
    hence deleq: "w. delta_price N cash_flow T n w = (rn_price N cash_flow T (Suc n) (spick w n True) - rn_price N cash_flow T (Suc n) (spick w n False))/
    ((geom_proc n w) * (u - d))" using delta_price_eq by simp
    have "(λw. rn_price N cash_flow T (Suc n) (spick w n True))  borel_measurable (G n)"
    proof -
      have "rn_price N cash_flow T (Suc n)  borel_measurable  (G (Suc n))" using rn_price_borel_adapt assms
        using True by blast
      moreover have "(λw. spick w n True)  G n M G (Suc n)" using spick_red_geom_filt by simp
      ultimately show ?thesis by simp
    qed
    moreover have "(λw. rn_price N cash_flow T (Suc n) (spick w n False))  borel_measurable (G n)"
    proof -
      have "rn_price N cash_flow T (Suc n)  borel_measurable  (G (Suc n))" using rn_price_borel_adapt assms
        using True by blast
      moreover have "(λw. spick w n False)  G n M G (Suc n)" using spick_red_geom_filt by simp
      ultimately show ?thesis by simp
    qed
    ultimately have "(λw. rn_price N cash_flow T (Suc n) (spick w n True) - rn_price N cash_flow T (Suc n) (spick w n False))
       borel_measurable (G n)" by simp
    moreover have "(λw. (geom_proc n w) * (u - d))  borel_measurable (G n)"
    proof -
      have "geom_proc n  borel_measurable (G n)" using stock_filtration
        by (metis adapt_stoch_proc_def stk_price stock_price_borel_measurable)
      thus ?thesis by simp
    qed
    ultimately have "(λw. (rn_price N cash_flow T (Suc n) (spick w n True) - rn_price N cash_flow T (Suc n) (spick w n False))/
      ((geom_proc n w) * (u - d))) borel_measurable (G n)" by simp
    thus ?thesis using deleq by presburger
  next
    case False
    thus ?thesis unfolding delta_price_def by simp
  qed
qed

fun (in CRR_market) delta_predict where
  "delta_predict N der matur 0  = (λw. delta_price N der matur 0 w)" |
  "delta_predict N der matur (Suc n) = (λw. delta_price N der matur n w)"

lemma (in CRR_market) delta_predict_predict:
  assumes "der  borel_measurable (G matur)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
  shows "borel_predict_stoch_proc G (delta_predict N der matur)" unfolding predict_stoch_proc_def
proof (intro conjI)
  show "delta_predict N der matur 0  borel_measurable (G 0)" using delta_price_adapted[of der matur N q]
    assms unfolding adapt_stoch_proc_def by force
  show "n. delta_predict N der matur (Suc n)  borel_measurable (G n)"
  proof
    fix n
    show "delta_predict N der matur (Suc n)  borel_measurable (G n)" using delta_price_adapted[of der matur N q]
    assms unfolding adapt_stoch_proc_def by force
  qed
qed


definition (in CRR_market) delta_pf where
"delta_pf N der matur = qty_single stk (delta_predict N der matur)"

lemma (in CRR_market) delta_pf_support:
  shows "support_set (delta_pf N der matur)  {stk}" unfolding delta_pf_def
  using single_comp_support[of stk "delta_predict N der matur"] by simp

definition (in CRR_market) self_fin_delta_pf where
"self_fin_delta_pf N der matur v0 = self_finance Mkt v0 (delta_pf N der matur) risk_free_asset"

lemma (in disc_equity_market) self_finance_trading_strat:
  assumes "trading_strategy pf"
and "portfolio pf"
and "borel_adapt_stoch_proc F (prices Mkt asset)"
and "support_adapt Mkt pf"
shows "trading_strategy (self_finance Mkt v pf asset)" unfolding self_finance_def
proof (rule sum_trading_strat)
  show "trading_strategy pf" using assms by simp
  show "trading_strategy (qty_single asset (remaining_qty Mkt v pf asset))" unfolding trading_strategy_def
  proof (intro conjI ballI)
  show "portfolio (qty_single asset (remaining_qty Mkt v pf asset))"
    by (simp add: self_finance_def single_comp_portfolio)
  show "a.
       a  support_set (qty_single asset (remaining_qty Mkt v pf asset)) 
       borel_predict_stoch_proc F (qty_single asset (remaining_qty Mkt v pf asset) a)"
  proof (cases "support_set (qty_single asset (remaining_qty Mkt v pf asset)) = {}")
    case False
    hence eqasset: "support_set (qty_single asset (remaining_qty Mkt v pf asset)) = {asset}"
      using single_comp_support by fastforce
    fix a
    assume "a support_set (qty_single asset (remaining_qty Mkt v pf asset))"
    hence "a = asset" using eqasset by simp
    hence "qty_single asset (remaining_qty Mkt v pf asset) a = (remaining_qty Mkt v pf asset)"
      unfolding qty_single_def by simp
    moreover have "borel_predict_stoch_proc F (remaining_qty Mkt v pf asset)"
    proof (rule remaining_qty_predict)
      show "trading_strategy pf" using assms by simp
      show "borel_adapt_stoch_proc F (prices Mkt asset)" using assms by simp
      show "support_adapt Mkt pf" using assms by simp
    qed
    ultimately show "borel_predict_stoch_proc F (qty_single asset (remaining_qty Mkt v pf asset) a)"
      by simp
  next
    case True
    thus "a. a  support_set (qty_single asset (remaining_qty Mkt v pf asset)) 
         support_set (qty_single asset (remaining_qty Mkt v pf asset)) = {} 
         borel_predict_stoch_proc F (qty_single asset (remaining_qty Mkt v pf asset) a)" by simp
  qed
qed
qed

lemma (in CRR_market) self_fin_delta_pf_trad_strat:
  assumes "der borel_measurable (G matur)"
and "N = bernoulli_stream q"
and "0 < q"
and "q < 1"
  shows "trading_strategy (self_fin_delta_pf N der matur v0)" unfolding self_fin_delta_pf_def
proof (rule self_finance_trading_strat)
  show "trading_strategy (delta_pf N der matur)" unfolding trading_strategy_def
  proof (intro conjI ballI)
    show "portfolio (delta_pf N der matur)" unfolding portfolio_def using delta_pf_support
      by (meson finite.emptyI finite_insert infinite_super)
    show "asset. asset  support_set (delta_pf N der matur)  borel_predict_stoch_proc G (delta_pf N der matur asset)"
    proof (cases "support_set (delta_pf N der matur) = {}")
      case False
      fix asset
      assume "asset  support_set (delta_pf N der matur)"
      hence "asset = stk" using False delta_pf_support by auto
      hence "delta_pf N der matur asset = delta_predict N der matur" unfolding delta_pf_def qty_single_def by simp
      thus "borel_predict_stoch_proc G (delta_pf N der matur asset)" using delta_predict_predict
        assms by simp
    next
      case True
      thus "asset. asset  support_set (delta_pf N der matur) 
             support_set (delta_pf N der matur) = {}  borel_predict_stoch_proc G (delta_pf N der matur asset)" by simp
    qed
  qed
  show "portfolio (delta_pf N der matur)" using delta_pf_support unfolding portfolio_def
    by (meson finite.emptyI finite_insert infinite_super)
  show "borel_adapt_stoch_proc G (prices Mkt risk_free_asset)" using rf_price
    disc_rfr_proc_borel_adapted by simp
  show "support_adapt Mkt (delta_pf N der matur)" unfolding support_adapt_def
  proof
    show "asset. asset  support_set (delta_pf N der matur)  borel_adapt_stoch_proc G (prices Mkt asset)"
    proof (cases "support_set (delta_pf N der matur) = {}")
      case False
      fix asset
      assume "asset  support_set (delta_pf N der matur)"
      hence "asset = stk" using False delta_pf_support by auto
      hence "prices Mkt asset = geom_proc" using stk_price by simp
      thus "borel_adapt_stoch_proc G (prices Mkt asset)"
        using asset = stk stock_price_borel_measurable by auto
    next
      case True
      thus "asset. asset  support_set (delta_pf N der matur)  borel_adapt_stoch_proc G (prices Mkt asset)"
        by simp
    qed
  qed
qed

definition (in CRR_market) delta_hedging where
"delta_hedging N der matur = self_fin_delta_pf N der matur
  (prob_space.expectation N (discounted_value r (λm. der) matur))"


lemma (in CRR_market)  geom_proc_eq_snth:
  shows "(m. m  Suc n  geom_proc m x = geom_proc m y) 
    (m. m  n  snth x m = snth y m)"
proof (induct n )
  case 0
  assume asm: "(m. m Suc  0  geom_proc m x = geom_proc m y)" and "m 0"
  hence "m = 0" by simp
  have "geom_proc (Suc 0) x = geom_proc (Suc 0) y" using asm by simp
  have "snth x 0 = snth y 0"
  proof (rule ccontr)
    assume "snth x 0  snth y 0"
    show False
    proof (cases "snth x 0")
      case True
      hence "¬ snth y 0" using snth x 0  snth y 0 by simp
      have "geom_proc (Suc 0) x = u * init" using geometric_process True by simp
      moreover have "geom_proc (Suc 0) y = d * init" using geometric_process ¬ snth y 0 by simp
      ultimately have "geom_proc (Suc 0) x  geom_proc (Suc 0) y" using S0_positive down_lt_up by simp
      thus ?thesis using geom_proc (Suc 0) x = geom_proc (Suc 0) y by simp
    next
      case False
      hence "snth y 0" using snth x 0  snth y 0 by simp
      have "geom_proc (Suc 0) x = d * init" using geometric_process False by simp
      moreover have "geom_proc (Suc 0) y = u * init" using geometric_process snth y 0 by simp
      ultimately have "geom_proc (Suc 0) x  geom_proc (Suc 0) y" using S0_positive down_lt_up by simp
      thus ?thesis using geom_proc (Suc 0) x = geom_proc (Suc 0) y by simp
    qed
  qed
  thus "m. (m. m  Suc 0  geom_proc m x = geom_proc m y)  m  0  x !! m = y !! m" by simp
next
  case (Suc n)
  assume fst: "(m. (m. m  Suc n  geom_proc m x = geom_proc m y)  m  n  x !! m = y !! m)"
    and scd: "(m. m  Suc (Suc n)  geom_proc m x = geom_proc m y)" and "m  Suc n"
  show "x !! m = y !! m"
  proof (cases "m  n")
    case True
    thus ?thesis using fst scd by simp
  next
    case False
    hence "m = Suc n" using m Suc n by simp
    have "geom_proc (Suc (Suc n)) x = geom_proc (Suc (Suc n)) y" using scd by simp
    show ?thesis
    proof (rule ccontr)
      assume "x !! m  y !! m"
      thus False
      proof (cases "x !! m")
        case True
        hence "¬ y !! m" using x !! m  y !! m by simp
        have "geom_proc (Suc (Suc n)) x = u * geom_proc (Suc n) x" using geometric_process True
          m = Suc n by simp
        also have "... = u * geom_proc (Suc n) y" using scd m = Suc n by simp
        finally have "geom_proc (Suc (Suc n)) x = u * geom_proc (Suc n) y" .
        moreover have "geom_proc (Suc (Suc n)) y = d * geom_proc (Suc n) y" using geometric_process
          m = Suc n ¬ y !! m by simp
        ultimately have "geom_proc (Suc (Suc n)) x  geom_proc (Suc (Suc n)) y"
          by (metis S0_positive down_lt_up down_positive geom_rand_walk_strictly_positive less_irrefl mult_cancel_right)
        thus ?thesis using geom_proc (Suc (Suc n)) x = geom_proc (Suc (Suc n)) y by simp
      next
        case False
        hence "y !! m" using x !! m  y !! m by simp
        have "geom_proc (Suc (Suc n)) x = d * geom_proc (Suc n) x" using geometric_process False
          m = Suc n by simp
        also have "... = d * geom_proc (Suc n) y" using scd m = Suc n by simp
        finally have "geom_proc (Suc (Suc n)) x = d * geom_proc (Suc n) y" .
        moreover have "geom_proc (Suc (Suc n)) y = u * geom_proc (Suc n) y" using geometric_process
          m = Suc n y !! m by simp
        ultimately have "geom_proc (Suc (Suc n)) x  geom_proc (Suc (Suc n)) y"
          by (metis S0_positive down_lt_up down_positive geom_rand_walk_strictly_positive less_irrefl mult_cancel_right)
        thus ?thesis using geom_proc (Suc (Suc n)) x = geom_proc (Suc (Suc n)) y by simp
      qed
    qed
  qed
qed

lemma (in CRR_market)  geom_proc_eq_pseudo_proj_True:
  shows "(m. m   n  geom_proc m x = geom_proc m y) 
    (pseudo_proj_True (n) x = pseudo_proj_True (n) y)"
  by (meson geom_proc_eq_snth le_trans order.refl pseudo_proj_True_snth')




lemma (in CRR_market)  proj_stoch_eq_pseudo_proj_True:
  assumes "proj_stoch_proc geom_proc m x = proj_stoch_proc geom_proc m y"
  shows "pseudo_proj_True m x = pseudo_proj_True m y"
proof -
  have " k  m. geom_proc k x = geom_proc k y"
  proof (intro allI impI)
    fix k
    assume "k  m"
    thus "geom_proc k x = geom_proc k y" using proj_stoch_proc_eq_snth[of geom_proc m x y k] assms by simp
  qed
  thus ?thesis  using geom_proc_eq_pseudo_proj_True[of m x y] by auto
qed

lemma (in CRR_market_viable) rn_rev_price_cond_expect:
  assumes "N = bernoulli_stream q"
and "0 <q"
and "q < 1"
and "der  borel_measurable (G matur)"
and "Suc n  matur"
shows "expl_cond_expect N (proj_stoch_proc geom_proc n) (rn_rev_price N der matur (matur - Suc n)) w=
  (q * rn_rev_price N der matur (matur - Suc n) (pseudo_proj_True n w)  +
      (1 - q) * rn_rev_price N der matur (matur - Suc n) (pseudo_proj_False n w))"
proof (rule infinite_cts_filtration.f_borel_Suc_expl_cond_expect)
  show "infinite_cts_filtration q N nat_filtration" using  assms  pslt psgt
    bernoulli_nat_filtration by simp
  show "rn_rev_price N der matur (matur - Suc n)  borel_measurable (nat_filtration (Suc n))"
    using rn_rev_price_rev_borel_adapt[of der matur N q "Suc n"]   assms
      stock_filtration stoch_proc_subalg_nat_filt[of geom_proc] geom_rand_walk_borel_adapted
    by (metis add_diff_cancel_right' diff_le_self measurable_from_subalg
        ordered_cancel_comm_monoid_diff_class.add_diff_inverse rn_rev_price_rev_borel_adapt)
  show "proj_stoch_proc geom_proc n  nat_filtration n M stream_space borel"
    using proj_stoch_adapted_if_adapted[of M nat_filtration geom_proc borel n]
    pslt psgt bernoulli_nat_filtration[of M p] bernoulli geom_rand_walk_borel_adapted
    nat_discrete_filtration by blast
  show "set_discriminating n (proj_stoch_proc geom_proc n) (stream_space borel)"
    using infinite_cts_filtration.proj_stoch_set_discriminating
    pslt psgt bernoulli_nat_filtration[of M p] bernoulli geom_rand_walk_borel_adapted by simp
  show "proj_stoch_proc geom_proc n -` {proj_stoch_proc geom_proc n w}  sets (nat_filtration n)"
    using infinite_cts_filtration.proj_stoch_singleton_set
    pslt psgt bernoulli_nat_filtration[of M p] bernoulli geom_rand_walk_borel_adapted by simp
  show "y z. proj_stoch_proc geom_proc n y = proj_stoch_proc geom_proc n z  y !! n = z !! n 
    rn_rev_price N der matur (matur - Suc n) y = rn_rev_price N der matur (matur - Suc n) z"
  proof (intro allI impI)
    fix y z
    assume as:"proj_stoch_proc geom_proc n y = proj_stoch_proc geom_proc n z  y !! n = z !! n"
    hence "pseudo_proj_True n y = pseudo_proj_True n z" using proj_stoch_eq_pseudo_proj_True[of n y z] by simp
    moreover have "snth y n = snth z n" using as by simp
    ultimately have "pseudo_proj_True (Suc n) y = pseudo_proj_True (Suc n) z"
      by (metis (full_types) pseudo_proj_True_def pseudo_proj_True_same_img stake_Suc)
    have "rn_rev_price N der matur (matur - Suc n) y =
      rn_rev_price N der matur (matur - Suc n) (pseudo_proj_True (Suc n) y)" using nat_filtration_info[of "rn_rev_price N der matur (matur - Suc n)" "Suc n"]
      rn_rev_price_rev_borel_adapt[of der matur N q]
      by (metis rn_rev_price N der matur (matur - Suc n)  borel_measurable (nat_filtration (Suc n)) o_apply)
    also have "... = rn_rev_price N der matur (matur - Suc n) (pseudo_proj_True (Suc n) z)"
      using pseudo_proj_True (Suc n) y = pseudo_proj_True (Suc n) z by simp
    also have "... = rn_rev_price N der matur (matur - Suc n) z" using nat_filtration_info[of "rn_rev_price N der matur (matur - Suc n)" "Suc n"]
      rn_rev_price_rev_borel_adapt[of der matur N q]
      by (metis rn_rev_price N der matur (matur - Suc n)  borel_measurable (nat_filtration (Suc n)) o_apply)
    finally show "rn_rev_price N der matur (matur - Suc n) y = rn_rev_price N der matur (matur - Suc n) z" .
  qed
  show "0 < q" and "q < 1" using assms by auto
qed




lemma (in CRR_market_viable) rn_price_eq_ind:
  assumes "N = bernoulli_stream q"
and "n < matur"
and "0 < q"
and "q < 1"
and "der  borel_measurable (G matur)"
shows "(1+r) * rn_price N der matur n w = q * rn_price N der matur (Suc n) (pseudo_proj_True n w) +
  (1 - q) * rn_price N der matur (Suc n) (pseudo_proj_False n w)"
proof -
  define V where "V = rn_price N der matur"
  let ?m = "matur - Suc n"
  have "matur -n = Suc ?m" by (simp add: assms Suc_diff_Suc Suc_le_lessD)
  have "(1+r) * V n w = (1+r) * rn_price_ind N der matur n w" using rn_price_eq assms unfolding V_def by simp
  also have "... = (1+r) * rn_rev_price N der matur (Suc ?m) w" using matur -n = Suc ?m
    unfolding rn_price_ind_def by simp
  also have "... = (1+r) * discount_factor r (Suc 0) w *
                    expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc ?m)) (rn_rev_price N der matur ?m) w"
    by simp
  also have "... = expl_cond_expect N (proj_stoch_proc geom_proc (matur - Suc ?m)) (rn_rev_price N der matur ?m) w"
    unfolding discount_factor_def using acceptable_rate by auto
  also have "... = expl_cond_expect N (proj_stoch_proc geom_proc n) (rn_rev_price N der matur ?m) w"
    using matur -n = Suc ?m by simp
  also have "... = (q * rn_rev_price N der matur ?m (pseudo_proj_True n w)  +
    (1 - q) * rn_rev_price N der matur ?m (pseudo_proj_False n w))"
    using rn_rev_price_cond_expect[of N q der matur n w] assms   by simp
  also have "... =  q * rn_price_ind N der matur (Suc n) (pseudo_proj_True n w) +
    (1 - q) * rn_price_ind N der matur (Suc n) (pseudo_proj_False n w)" unfolding rn_price_ind_def by simp
  also have "... = q * rn_price N der matur (Suc n) (pseudo_proj_True n w) +
    (1 - q) * rn_price N der matur (Suc n) (pseudo_proj_False n w)" using rn_price_eq assms  by simp
  also have "... = q * V (Suc n) (pseudo_proj_True n w) + (1 - q) *V (Suc n) (pseudo_proj_False n w)"
    unfolding V_def by simp
  finally have "(1+r) * V n w = q * V (Suc n) (pseudo_proj_True n w) + (1 - q) *V (Suc n) (pseudo_proj_False n w)" .
  thus ?thesis unfolding V_def by simp
qed



lemma self_finance_updated_suc_suc:
  assumes "portfolio pf"
  and "n. prices Mkt asset n w  0"
  shows "cls_val_process Mkt (self_finance Mkt v pf asset) (Suc (Suc n)) w = cls_val_process Mkt pf (Suc (Suc n)) w +
    (prices Mkt asset (Suc (Suc n)) w / (prices Mkt asset (Suc n) w)) *
      (cls_val_process Mkt (self_finance Mkt v pf asset) (Suc n) w -
     val_process Mkt pf (Suc n) w)"
proof -
  have "cls_val_process Mkt (self_finance Mkt v pf asset) (Suc (Suc n)) w = cls_val_process Mkt pf (Suc (Suc n)) w +
    prices Mkt asset (Suc (Suc n)) w * remaining_qty Mkt v pf asset (Suc (Suc n)) w" using assms
    by (simp add: self_finance_updated)
  also have "... = cls_val_process Mkt pf (Suc (Suc n)) w +
    prices Mkt asset (Suc (Suc n)) w * ((remaining_qty Mkt v pf asset (Suc n) w) +
    (cls_val_process Mkt pf (Suc n) w - val_process Mkt pf (Suc n) w)/(prices Mkt asset (Suc n) w))"
    by simp
  also have "... = cls_val_process Mkt pf (Suc (Suc n)) w +
    prices Mkt asset (Suc (Suc n)) w *
      ((prices Mkt asset (Suc n) w) * (remaining_qty Mkt v pf asset (Suc n) w) / (prices Mkt asset (Suc n) w) +
    (cls_val_process Mkt pf (Suc n) w - val_process Mkt pf (Suc n) w)/(prices Mkt asset (Suc n) w))" using assms
    by (metis nonzero_mult_div_cancel_left)
  also have "... = cls_val_process Mkt pf (Suc (Suc n)) w +
    prices Mkt asset (Suc (Suc n)) w * ((prices Mkt asset (Suc n) w) * (remaining_qty Mkt v pf asset (Suc n) w) +
    cls_val_process Mkt pf (Suc n) w - val_process Mkt pf (Suc n) w)/(prices Mkt asset (Suc n) w)"
    using add_divide_distrib[symmetric, of "prices Mkt asset (Suc n) w * remaining_qty Mkt v pf asset (Suc n) w"
        "prices Mkt asset (Suc n) w"]  by simp
  also have "... = cls_val_process Mkt pf (Suc (Suc n)) w +
    (prices Mkt asset (Suc (Suc n)) w / (prices Mkt asset (Suc n) w)) *
    ((prices Mkt asset (Suc n) w) * (remaining_qty Mkt v pf asset (Suc n) w) +
    cls_val_process Mkt pf (Suc n) w - val_process Mkt pf (Suc n) w)" by simp
  also have "... = cls_val_process Mkt pf (Suc (Suc n)) w +
    (prices Mkt asset (Suc (Suc n)) w / (prices Mkt asset (Suc n) w)) *
      (cls_val_process Mkt (self_finance Mkt v pf asset) (Suc n) w -
     val_process Mkt pf (Suc n) w)"
    using self_finance_updated[of Mkt asset n w pf v] assms by auto
  finally show ?thesis .
qed

lemma self_finance_updated_suc_0:
  assumes "portfolio pf"
  and "n w. prices Mkt asset n w  0"
  shows "cls_val_process Mkt (self_finance Mkt v pf asset) (Suc 0) w = cls_val_process Mkt pf (Suc 0) w +
    (prices Mkt asset (Suc 0) w / (prices Mkt asset 0 w)) *
      (val_process Mkt (self_finance Mkt v pf asset) 0 w -
     val_process Mkt pf 0 w)"
proof -
  have "cls_val_process Mkt (self_finance Mkt v pf asset) (Suc 0) w = cls_val_process Mkt pf (Suc 0) w +
    prices Mkt asset (Suc 0) w * remaining_qty Mkt v pf asset (Suc 0) w" using assms
    by (simp add: self_finance_updated)
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    prices Mkt asset (Suc 0) w * ((v - val_process Mkt pf 0 w)/(prices Mkt asset 0 w))"
    by simp
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    prices Mkt asset (Suc 0) w * ((remaining_qty Mkt v pf asset 0 w) +
    (v - val_process Mkt pf 0 w)/(prices Mkt asset 0 w))"
    by simp
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    prices Mkt asset (Suc 0) w *
      ((prices Mkt asset 0 w) * (remaining_qty Mkt v pf asset 0 w) / (prices Mkt asset 0 w) +
    (v - val_process Mkt pf 0 w)/(prices Mkt asset 0 w))" using assms
    by (metis nonzero_mult_div_cancel_left)
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    prices Mkt asset (Suc 0) w * ((prices Mkt asset 0 w) * (remaining_qty Mkt v pf asset 0 w) +
    v - val_process Mkt pf 0 w)/(prices Mkt asset 0 w)"
    using add_divide_distrib[symmetric, of "prices Mkt asset 0 w * remaining_qty Mkt v pf asset 0 w"
        "prices Mkt asset 0 w"]  by simp
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    (prices Mkt asset (Suc 0) w / (prices Mkt asset 0 w)) *
    ((prices Mkt asset 0 w) * (remaining_qty Mkt v pf asset 0 w) +
    v - val_process Mkt pf 0 w)" by simp
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    (prices Mkt asset (Suc 0) w / (prices Mkt asset 0 w)) *
    ((prices Mkt asset 0 w) * (remaining_qty Mkt v pf asset 0 w) +
    val_process Mkt (self_finance Mkt v pf asset) 0 w - val_process Mkt pf 0 w)"
    using self_finance_init[of Mkt asset pf v w] assms by simp
  also have "... = cls_val_process Mkt pf (Suc 0) w +
    (prices Mkt asset (Suc 0) w / (prices Mkt asset 0 w)) *
      (val_process Mkt (self_finance Mkt v pf asset) 0 w -
     val_process Mkt pf 0 w)" by simp
  finally show ?thesis .
qed

lemma self_finance_updated_ind:
  assumes "portfolio pf"
  and "n w. prices Mkt asset n w  0"
  shows "cls_val_process Mkt (self_finance Mkt v pf asset) (Suc n) w = cls_val_process Mkt pf (Suc n) w +
    (prices Mkt asset (Suc n) w / (prices Mkt asset n w)) *
      (val_process Mkt (self_finance Mkt v pf asset) n w -
     val_process Mkt pf n w)"
proof (cases "n = 0")
  case True
  thus ?thesis using assms self_finance_updated_suc_0 by simp
next
  case False
  hence "m. n = Suc m" by (simp add: not0_implies_Suc)
  from this obtain m where "n = Suc m" by auto
  hence "cls_val_process Mkt (self_finance Mkt v pf asset) (Suc n) w =
    cls_val_process Mkt (self_finance Mkt v pf asset) (Suc (Suc m)) w" by simp
  also have "...  = cls_val_process Mkt pf (Suc (Suc m)) w +
    (prices Mkt asset (Suc (Suc m)) w / (prices Mkt asset (Suc m) w)) *
      (cls_val_process Mkt (self_finance Mkt v pf asset) (Suc m) w -
     val_process Mkt pf (Suc m) w)" using assms self_finance_updated_suc_suc[of pf] by simp
  also have "... = cls_val_process Mkt pf (Suc (Suc m)) w +
    (prices Mkt asset (Suc (Suc m)) w / (prices Mkt asset (Suc m) w)) *
      (val_process Mkt (self_finance Mkt v pf asset) (Suc m) w -
     val_process Mkt pf (Suc m) w)" using assms self_finance_charact unfolding self_financing_def
    by (simp add: self_finance_succ self_finance_updated)
  also have "... = cls_val_process Mkt pf (Suc n) w +
    (prices Mkt asset (Suc n) w / (prices Mkt asset n w)) *
      (val_process Mkt (self_finance Mkt v pf asset) n w -
     val_process Mkt pf n w)" using n = Suc m by simp
  finally show ?thesis .
qed


lemma  (in rfr_disc_equity_market) self_finance_risk_free_update_ind:
  assumes "portfolio pf"
  shows "cls_val_process Mkt (self_finance Mkt v pf risk_free_asset) (Suc n) w = cls_val_process Mkt pf (Suc n) w +
    (1 + r) * (val_process Mkt (self_finance Mkt v pf risk_free_asset) n w - val_process Mkt pf n w)"
proof -
  have "cls_val_process Mkt (self_finance Mkt v pf risk_free_asset) (Suc n) w =
    cls_val_process Mkt pf (Suc n) w +
    (prices Mkt risk_free_asset (Suc n) w / (prices Mkt risk_free_asset n w)) *
      (val_process Mkt (self_finance Mkt v pf risk_free_asset) n w -
     val_process Mkt pf n w)"
  proof (rule self_finance_updated_ind, (simp add: assms), intro allI)
    fix n w
    show "prices Mkt risk_free_asset n w  0" using positive by (metis less_irrefl)
  qed
  also have "... = cls_val_process Mkt pf (Suc n) w +
    (1+r) * (val_process Mkt (self_finance Mkt v pf risk_free_asset) n w -
     val_process Mkt pf n w)" using rf_price  positive
    by (metis acceptable_rate disc_rfr_proc_Suc_div)
  finally show ?thesis .
qed



lemma (in CRR_market) delta_pf_portfolio:
  shows "portfolio (delta_pf N der matur)" unfolding delta_pf_def by (simp add: single_comp_portfolio)

lemma (in CRR_market) delta_pf_updated:
  shows "cls_val_process Mkt (delta_pf N der matur) (Suc n) w =
    geom_proc (Suc n) w * delta_price N der matur n w" unfolding delta_pf_def
    using stk_price qty_single_updated[of Mkt] by simp

lemma (in CRR_market) delta_pf_val_process:
  shows "val_process Mkt (delta_pf N der matur) n w =
    geom_proc n w * delta_price N der matur n w" unfolding delta_pf_def
  using stk_price qty_single_val_process[of Mkt] by simp

lemma (in CRR_market) delta_hedging_cls_val_process:
  shows "cls_val_process Mkt (delta_hedging N der matur) (Suc n) w =
    geom_proc (Suc n) w * delta_price N der matur n w +
    (1 + r) * (val_process Mkt (delta_hedging N der matur) n w - geom_proc n w * delta_price N der matur n w)"
proof -
  define X where "X = delta_hedging N der matur"
  define init where "init = integralL N (discounted_value r (λm. der) matur)"
  have "cls_val_process Mkt X (Suc n) w = cls_val_process Mkt (delta_pf N der matur) (Suc n) w +
    (1 + r) * (val_process Mkt X n w - val_process Mkt (delta_pf N der matur) n w)"
    unfolding X_def delta_hedging_def self_fin_delta_pf_def init_def
  proof (rule self_finance_risk_free_update_ind)
    show "portfolio (delta_pf N der matur)" unfolding  portfolio_def using delta_pf_support
      by (meson finite.simps infinite_super)
  qed
  also have "... = geom_proc (Suc n) w * delta_price N der matur n w +
    (1 + r) * (val_process Mkt X n w - val_process Mkt (delta_pf N der matur) n w)"
    using delta_pf_updated by simp
  also have "... = geom_proc (Suc n) w * delta_price N der matur n w +
    (1 + r) * (val_process Mkt X n w - geom_proc n w * delta_price N der matur n w)"
    using delta_pf_val_process by simp
  finally show ?thesis unfolding X_def .
qed







lemma (in CRR_market_viable) delta_hedging_eq_derivative_price:
  fixes der::"bool stream  real" and matur::nat
  assumes "N = bernoulli_stream ((1 + r - d) / (u - d))"
  and "der borel_measurable (G matur)"
  shows "n w. n matur 
    val_process Mkt (delta_hedging N der matur) n w =
    (rn_price N der matur) n w"
unfolding delta_hedging_def
proof -
  define q where "q = (1 + r - d) / (u - d)"
  have "0 < q" and "q < 1" unfolding q_def using assms gt_param lt_param CRR_viable by auto
  note qprops = this
  define init where  "init = (prob_space.expectation N (discounted_value r (λm. der) matur))"
  define X where "X = val_process Mkt (delta_hedging N der matur)"
  define V where "V = rn_price N der matur"
  define Δ where "Δ = delta_price N der matur"
  {
    fix n
    fix w
    have "n  matur  X n w = V n w"
    proof (induct n)
    case 0
    have v0: "V 0  borel_measurable (G 0)" using assms rn_price_borel_adapt "0.prems" qprops
      unfolding V_def q_def by auto
    have "X 0 w= init" using self_finance_init[of Mkt risk_free_asset "delta_pf N der matur" "integralL N (discounted_value r (λm. der) matur)"]
        delta_pf_support
      unfolding  X_def init_def delta_hedging_def self_fin_delta_pf_def init_def
      by (metis finite_insert infinite_imp_nonempty infinite_super less_irrefl portfolio_def positive)
    also have "... = V 0 w" 
    proof -
      have "xspace N. real_cond_exp N (G 0) (discounted_value r (λm. der) matur) x =
        integralL N (discounted_value r (λm. der) matur)"
      proof (rule prob_space.trivial_subalg_cond_expect_eq)
        show "prob_space N" using assms qprops unfolding q_def
          by (simp add: bernoulli bernoulli_stream_def prob_space.prob_space_stream_space prob_space_measure_pmf)
        have "init_triv_filt M (stoch_proc_filt M geom_proc borel)"
        proof (rule infinite_cts_filtration.stoch_proc_filt_triv_init)
          show "borel_adapt_stoch_proc nat_filtration geom_proc" using geom_rand_walk_borel_adapted by simp
          show "infinite_cts_filtration p M nat_filtration" using bernoulli_nat_filtration[of M p] bernoulli psgt pslt
            by simp
        qed
        hence "init_triv_filt N (stoch_proc_filt M geom_proc borel)" using assms qprops
          filt_equiv_triv_init[of nat_filtration N] stock_filtration
          bernoulli_stream_equiv[of N] psgt pslt unfolding q_def by simp
        thus "subalgebra N (G 0)" and "sets (G 0) = {{}, space N}" using stock_filtration unfolding init_triv_filt_def
          filtration_def bot_nat_def by auto
        show "integrable N (discounted_value r (λm. der) matur)"
        proof (rule bernoulli_discounted_integrable)
          show "der  borel_measurable (nat_filtration matur)" using assms geom_rand_walk_borel_adapted
              measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
          show "N = bernoulli_stream q" using assms unfolding q_def by simp
          show "0 < q" "q < 1" using qprops by auto
        qed (simp add: acceptable_rate)
      qed
      hence "integralL N (discounted_value r (λm. der) matur) =
        real_cond_exp N (G 0) (discounted_value r (λm. der) matur) w" using bernoulli_stream_space[of N q]
        by (simp add: assms(1) q_def)
      also have "... = real_cond_exp N (stoch_proc_filt M geom_proc borel 0) (discounted_value r (λm. der) matur) w"
        using stock_filtration by simp
      also have "... = real_cond_exp N (stoch_proc_filt N geom_proc borel 0) (discounted_value r (λm. der) matur) w"
        using stoch_proc_filt_filt_equiv[of nat_filtration M N geom_proc]
          bernoulli_stream_equiv[of N] q_def qprops assms pslt psgt by auto
      also have "... = expl_cond_expect N (proj_stoch_proc geom_proc 0) (discounted_value r (λm. der) matur) w"
      proof (rule bernoulli_cond_exp)
        show "N = bernoulli_stream q" using assms unfolding q_def by simp
        show "0 < q" "q < 1" using qprops by auto
        show "integrable N (discounted_value r (λm. der) matur)"
        proof (rule bernoulli_discounted_integrable)
          show "der  borel_measurable (nat_filtration matur)" using assms geom_rand_walk_borel_adapted
              measurable_from_subalg stoch_proc_subalg_nat_filt stock_filtration by blast
          show "N = bernoulli_stream q" using assms unfolding q_def by simp
          show "0 < q" "q < 1" using qprops by auto
        qed (simp add: acceptable_rate)
      qed
      finally show "init = V 0 w" unfolding init_def V_def rn_price_def by simp
    qed
    finally show "X 0 w = V 0 w" .
    next
      case (Suc n)
      hence "n < matur" by simp
      show ?case
      proof -
        have "X n w = V n w" using Suc by (simp add: Suc.hyps Suc.prems Suc_leD)
        have "0< 1+r" using acceptable_rate by simp
        let ?m = "matur - Suc n"
        have "matur -n = Suc ?m" by (simp add: Suc.prems Suc_diff_Suc Suc_le_lessD)
        have "(1+r) * V n w = q * V (Suc n) (pseudo_proj_True n w) + (1 - q) *V (Suc n) (pseudo_proj_False n w)"
          using rn_price_eq_ind qprops assms Suc q_def V_def by simp
        show "X (Suc n) w = V (Suc n) w"
        proof (cases "snth w n")
        case True
          hence pseq: "pseudo_proj_True (Suc n) w = pseudo_proj_True (Suc n) (spick w n True)"
            by (metis (mono_tags, lifting) pseudo_proj_True_stake_image spickI stake_Suc)
          have "X (Suc n) w = cls_val_process Mkt (delta_hedging N der matur) (Suc n) w"
            unfolding X_def delta_hedging_def self_fin_delta_pf_def using  delta_pf_portfolio
            unfolding self_financing_def
            by (metis less_irrefl positive self_finance_charact self_financingE)
          also have "... = geom_proc (Suc n) w * Δ n w + (1 + r) * (X n w - geom_proc n w * Δ n w)"
            using delta_hedging_cls_val_process unfolding X_def Δ_def by simp
          also have "... = u * geom_proc n w * Δ n w + (1 + r) * (X n w - geom_proc n w * Δ n w)"
            using True geometric_process by simp
          also have "... = u * geom_proc n w * Δ n w + (1 + r) * X n w - (1+r) * geom_proc n w * Δ n w"
            by (simp add: right_diff_distrib)
          also have "... = (1+r) * X n w + geom_proc n w * Δ n w * u - geom_proc n w * Δ n w * (1 + r)"
            by (simp add: mult.commute mult.left_commute)
          also have "... = (1+r)* X n w + geom_proc n w * Δ n w * (u - (1 + r))" by (simp add: right_diff_distrib)
          also have "... = (1+r) * X n w + geom_proc n w * (V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w))/
            (geom_proc (Suc n) (spick w n True) - geom_proc (Suc n) (spick w n False)) * (u - (1 + r))"
            using Suc V_def by (simp add: Δ_def delta_price_def geom_rand_walk_diff_induct)
          also have "... = (1+r) * X n w + geom_proc n w * ((V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w))) /
            (geom_proc n w * (u - d)) * (u - (1 + r))"
          proof -
            have "geom_proc (Suc n) (spick w n True) - geom_proc (Suc n) (spick w n False) =
              geom_proc n w * (u - d)"
              by (simp add: geom_rand_walk_diff_induct)
            then show ?thesis by simp
          qed
          also have "... = (1+r) * X n w + ((V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w)))* (u - (1 + r))/ (u-d)"
          proof -
            have "geom_proc n w  0"
              by (metis S0_positive down_lt_up down_positive geom_rand_walk_strictly_positive less_irrefl)
            then show ?thesis
              by simp
          qed
          also have "... = (1+r) * X n w + ((V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w))* (1 - q))"
          proof -
            have "1 - q = 1 - (1 + r - d)/(u -d)" unfolding q_def by simp
            also have "... = (u - d)/(u - d) - (1 + r - d)/(u -d)" using down_lt_up by simp
            also have "... = (u - d - (1 + r - d))/(u - d)" using diff_divide_distrib[of "u - d" "1 + r -d"] by simp
            also have "... = (u - (1+r))/(u-d)" by simp
            finally have "1 - q = (u - (1+r))/(u-d)" .
            thus ?thesis by simp
          qed
          also have "... = (1+r) * X n w + (1 - q) * V (Suc n) (pseudo_proj_True n w) -
            (1 - q) * V (Suc n) (pseudo_proj_False n w)"
            by (simp add: mult.commute right_diff_distrib)
          also have "... = (1+r) * V n w + (1 - q) * V (Suc n) (pseudo_proj_True n w) -
            (1 - q) * V (Suc n) (pseudo_proj_False n w)" using X n w = V n w by simp
          also have "... = q * V (Suc n) (pseudo_proj_True n w) + (1 - q) * V (Suc n) (pseudo_proj_False n w) +
            (1 - q) * V (Suc n) (pseudo_proj_True n w) - (1 - q) * V (Suc n) (pseudo_proj_False n w)"
          using assms Suc rn_price_eq_ind[of N q n matur der w] n < matur qprops unfolding V_def q_def
            by simp
          also have "... = q * V (Suc n) (pseudo_proj_True n w) + (1 - q) * V (Suc n) (pseudo_proj_True n w)" by simp
          also have "... = V (Suc n) (pseudo_proj_True n w)"
            using distrib_right[of q "1 - q"  "V (Suc n) (pseudo_proj_True n w)"] by simp
          also have "... = V (Suc n) w"
          proof -
            have "V (Suc n)  borel_measurable (G (Suc n))" unfolding V_def q_def
            proof (rule rn_price_borel_adapt)
              show "der  borel_measurable (G matur)" using assms by simp
              show "N = bernoulli_stream q" using assms unfolding q_def by simp
              show "0 < q" and "q < 1" using qprops by auto
              show "Suc n  matur" using Suc by simp
            qed
            hence "V (Suc n) (pseudo_proj_True n w) = V (Suc n) (pseudo_proj_True (Suc n) (pseudo_proj_True n w))"
              using  geom_proc_filt_info[of "V (Suc n)" "Suc n"] by simp
            also have "... = V (Suc n) (pseudo_proj_True (Suc n) w)" using True
              by (simp add: pseq spick_eq_pseudo_proj_True)
            also have "... = V (Suc n) w" using V (Suc n)  borel_measurable (G (Suc n))
              geom_proc_filt_info[of "V (Suc n)" "Suc n"] by simp
            finally show ?thesis .
          qed
          finally show "X (Suc n) w = V (Suc n) w" .
        next
        case False
          hence pseq: "pseudo_proj_True (Suc n) w = pseudo_proj_True (Suc n) (spick w n False)" using filtration
            by (metis (full_types) pseudo_proj_True_def spickI stake_Suc)
          have "X (Suc n) w = cls_val_process Mkt (delta_hedging N der matur) (Suc n) w"
            unfolding X_def delta_hedging_def self_fin_delta_pf_def using  delta_pf_portfolio
            unfolding self_financing_def
            by (metis less_irrefl positive self_finance_charact self_financingE)
          also have "... = geom_proc (Suc n) w * Δ n w + (1 + r) * (X n w - geom_proc n w * Δ n w)"
            using delta_hedging_cls_val_process unfolding X_def Δ_def by simp
          also have "... = d * geom_proc n w * Δ n w + (1 + r) * (X n w - geom_proc n w * Δ n w)"
            using False geometric_process by simp
          also have "... = d * geom_proc n w * Δ n w + (1 + r) * X n w - (1+r) * geom_proc n w * Δ n w"
            by (simp add: right_diff_distrib)
          also have "... = (1+r) * X n w + geom_proc n w * Δ n w * d - geom_proc n w * Δ n w * (1 + r)"
            by (simp add: mult.commute mult.left_commute)
          also have "... = (1+r)* X n w + geom_proc n w * Δ n w * (d - (1 + r))" by (simp add: right_diff_distrib)
          also have "... = (1+r) * X n w + geom_proc n w * (V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w))/
            (geom_proc (Suc n) (spick w n True) - geom_proc (Suc n) (spick w n False)) * (d - (1 + r))"
            using Suc V_def by (simp add: Δ_def delta_price_def geom_rand_walk_diff_induct)
          also have "... = (1+r) * X n w + geom_proc n w * ((V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w))) /
            (geom_proc n w * (u - d)) * (d - (1 + r))"
            by (simp add: geom_rand_walk_diff_induct)
          also have "... = (1+r) * X n w + ((V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w)))* (d - (1 + r))/ (u-d)"
          proof -
            have "geom_proc n w  0"
              by (metis S0_positive down_lt_up down_positive geom_rand_walk_strictly_positive less_irrefl)
            then show ?thesis
              by simp
          qed
          also have "... = (1+r) * X n w + ((V (Suc n) (pseudo_proj_True n w) - V (Suc n) (pseudo_proj_False n w))* (-q))"
          proof -
            have "0-q = 0-(1 + r - d)/(u -d)" unfolding q_def by simp
            also have "... = (d - (1 + r))/(u -d)" by (simp add: minus_divide_left)
            finally have "0 - q = (d - (1+r))/(u-d)" .
            thus ?thesis by simp
          qed
          also have "... = (1+r) * X n w + (- V (Suc n) (pseudo_proj_True n w) * q + V (Suc n) (pseudo_proj_False n w)* q)"
            by (metis (no_types, opaque_lifting) add.inverse_inverse distrib_right minus_mult_commute minus_real_def mult_minus_left)
          also have "... = (1+r) * X n w - q * V (Suc n) (pseudo_proj_True n w) + q * V (Suc n) (pseudo_proj_False n w)" by simp
          also have "... = (1+r) * V n w -q * V (Suc n) (pseudo_proj_True n w) +
            q * V (Suc n) (pseudo_proj_False n w)" using X n w = V n w by simp
          also have "... = q * V (Suc n) (pseudo_proj_True n w) + (1 - q) * V (Suc n) (pseudo_proj_False n w) -
            q * V (Suc n) (pseudo_proj_True n w) + q * V (Suc n) (pseudo_proj_False n w)"
            using assms Suc rn_price_eq_ind[of N q n matur der w] n < matur qprops unfolding V_def q_def
            by simp
          also have "... = (1-q) * V (Suc n) (pseudo_proj_False n w) + q * V (Suc n) (pseudo_proj_False n w)" by simp
          also have "... = V (Suc n) (pseudo_proj_False n w)"
            using distrib_right[of q "1 - q"  "V (Suc n) (pseudo_proj_False n w)"] by simp
          also have "... = V (Suc n) w"
          proof -
            have "V (Suc n)  borel_measurable (G (Suc n))" unfolding V_def q_def
            proof (rule rn_price_borel_adapt)
              show "der  borel_measurable (G matur)" using assms by simp
              show "N = bernoulli_stream q" using assms unfolding q_def by simp
              show "0 < q" and "q < 1" using qprops by auto
              show "Suc n  matur" using Suc by simp
            qed
            hence "V (Suc n) (pseudo_proj_False n w) = V (Suc n) (pseudo_proj_False (Suc n) (pseudo_proj_False n w))"
              using  geom_proc_filt_info'[of "V (Suc n)" "Suc n"] by simp
            also have "... = V (Suc n) (pseudo_proj_False (Suc n) w)" using False  spick_eq_pseudo_proj_False
              by (metis pseq pseudo_proj_True_imp_False)
            also have "... = V (Suc n) w" using V (Suc n)  borel_measurable (G (Suc n))
              geom_proc_filt_info'[of "V (Suc n)" "Suc n"] by simp
            finally show ?thesis .
          qed
          finally show "X (Suc n) w = V (Suc n) w" .
        qed
      qed
    qed
  }
  thus "n w. n  matur 
           val_process Mkt (self_fin_delta_pf N der matur (integralL N (discounted_value r (λm. der) matur))) n w =
            rn_price N der matur n w" by (simp add: X_def init_def V_def delta_hedging_def)
qed


lemma (in CRR_market_viable) delta_hedging_same_cash_flow:
  assumes "der  borel_measurable (G matur)"
and "N = bernoulli_stream ((1 + r - d) / (u - d))"
  shows "cls_val_process Mkt (delta_hedging N der matur) matur w =
    der w"
proof  -
  define q where "q = (1 + r - d) / (u - d)"
  have "0 < q" and "q < 1" unfolding q_def using assms gt_param lt_param CRR_viable by auto
  note qprops = this
  have "cls_val_process Mkt (delta_hedging N der matur) matur w =
    val_process Mkt (delta_hedging N der matur) matur w" using self_financingE self_finance_charact
    unfolding delta_hedging_def self_fin_delta_pf_def
    by (metis delta_pf_portfolio mult_1s(1) mult_cancel_right not_real_square_gt_zero positive)
  also have "... = rn_price N der matur matur w" using delta_hedging_eq_derivative_price assms by simp
  also have "... = rn_rev_price N der matur 0 w" using rn_price_eq qprops assms
    unfolding rn_price_ind_def q_def by simp
  also have "... = der w" by simp
  finally show ?thesis .
qed

lemma (in CRR_market) delta_hedging_trading_strat:
  assumes "N = bernoulli_stream q"
  and "0 < q"
and "q < 1"
and "der  borel_measurable (G matur)"
  shows "trading_strategy (delta_hedging N der matur)" unfolding delta_hedging_def
  by (simp add: assms self_fin_delta_pf_trad_strat)

lemma (in CRR_market) delta_hedging_self_financing:
  shows "self_financing Mkt (delta_hedging N der matur)" unfolding delta_hedging_def self_fin_delta_pf_def
proof (rule self_finance_charact)
  show "n w. prices Mkt risk_free_asset (Suc n) w  0" using positive
    by (metis less_numeral_extra(3))
  show "portfolio (delta_pf N der matur)" using delta_pf_portfolio .
qed

lemma (in CRR_market_viable) delta_hedging_replicating:
  assumes "der  borel_measurable (G matur)"
  and "N = bernoulli_stream ((1 + r - d) / (u - d))"
  shows "replicating_portfolio (delta_hedging N der matur) der matur"
unfolding replicating_portfolio_def
proof (intro conjI)
  define q where "q = (1 + r - d) / (u - d)"
  have "0 < q" and "q < 1" unfolding q_def using assms gt_param lt_param CRR_viable by auto
  note qprops = this
  let ?X = "(delta_hedging N der matur)"
  show "trading_strategy ?X" using delta_hedging_trading_strat qprops assms unfolding q_def by simp
  show "self_financing Mkt ?X" using delta_hedging_self_financing .
  show "stock_portfolio Mkt (delta_hedging N der matur)" unfolding delta_hedging_def self_fin_delta_pf_def
    stock_portfolio_def portfolio_def using stocks delta_pf_support
    by (smt Un_insert_right delta_pf_portfolio insert_commute portfolio_def self_finance_def
        self_finance_portfolio single_comp_support subset_insertI2 subset_singleton_iff
        sum_support_set sup_bot.right_neutral)
  show "AEeq M (cls_val_process Mkt (delta_hedging N der matur) matur) der"
    using delta_hedging_same_cash_flow assms by simp
qed

definition (in disc_equity_market) complete_market where
"complete_market  (matur.  der borel_measurable (F matur). (p. replicating_portfolio p der matur))"

lemma (in CRR_market_viable) CRR_market_complete:
  shows "complete_market" unfolding complete_market_def
proof (intro allI impI)
  fix matur::nat
  show " der  borel_measurable (G matur). (p. replicating_portfolio p der matur)"
  proof
    fix der::"bool streamreal"
    assume "der  borel_measurable (G matur)"
    define N where "N = bernoulli_stream ((1 + r - d) / (u - d))"
    hence "replicating_portfolio (delta_hedging N der matur) der matur" using delta_hedging_replicating
      der  borel_measurable (G matur) by simp
    thus "pf. replicating_portfolio pf der matur" by auto
  qed
qed


lemma subalgebras_filtration:
  assumes "filtration M F"
and "t. subalgebra (F t) (G t)"
and " s t. s  t  subalgebra (G t) (G s)"
shows "filtration M G" unfolding filtration_def
proof (intro conjI allI impI)
  {
    fix t
    have "subalgebra (F t) (G t)" using assms by simp
    moreover have "subalgebra M (F t)" using assms unfolding filtration_def by simp
    ultimately show "subalgebra M (G t)" by (metis subalgebra_def subsetCE subsetI)
  }
  {
    fix s t::'b
    assume "s  t"
    thus "subalgebra (G t) (G s)" using assms by simp
  }
qed



lemma subfilt_filt_equiv:
  assumes "filt_equiv F M N"
and " t. subalgebra (F t) (G t)"
and " s t. s  t  subalgebra (G t) (G s)"
shows "filt_equiv G M N" unfolding filt_equiv_def
proof (intro conjI)
  show "sets M = sets N" using assms unfolding filt_equiv_def by simp
  show "filtration M G" using assms subalgebras_filtration[of M F G] unfolding filt_equiv_def by simp
  show "t A. A  sets (G t)  (emeasure M A = 0) = (emeasure N A = 0)"
  proof (intro allI ballI impI)
    fix t
    fix A
    assume "A sets (G t)"
    hence "A  sets (F t)" using assms unfolding subalgebra_def by auto
    thus "(emeasure M A = 0) = (emeasure N A = 0)" using assms unfolding filt_equiv_def by simp
  qed
qed

lemma (in CRR_market_viable) CRR_market_fair_price:
  assumes "pyf borel_measurable (G matur)"
  shows "fair_price Mkt
    ( w range (pseudo_proj_True matur). (prod (prob_component ((1 + r - d) / (u - d)) w) {0..<matur}) *
      ((discounted_value r (λm. pyf) matur) w))
    pyf matur"
proof -
  define dpf where "dpf = (discounted_value r (λm. pyf) matur)"
  define q where "q = (1 + r - d) / (u - d)"
  have "pf. replicating_portfolio pf pyf matur" using CRR_market_complete assms unfolding complete_market_def by simp
  from this obtain pf where "replicating_portfolio pf pyf matur" by auto note pfprop = this
  define N where "N = bernoulli_stream ((1 + r - d) / (u - d))"
  have "fair_price Mkt (integralL N dpf) pyf matur" unfolding dpf_def
  proof (rule replicating_expectation_finite)
    show "risk_neutral_prob N" using assms risk_neutral_iff
      using CRR_viable gt_param lt_param N_def by blast
    have "filt_equiv nat_filtration M N"  using bernoulli_stream_equiv[of N "(1+r-d)/(u-d)"]
        assms gt_param lt_param CRR_viable psgt pslt N_def by simp
    thus "filt_equiv G M N" using subfilt_filt_equiv
      using Filtration.filtration_def filtration geom_rand_walk_borel_adapted
        stoch_proc_subalg_nat_filt stock_filtration by blast
    show "pyf  borel_measurable (G matur)" using assms by simp
    show "viable_market Mkt" using CRR_viable by simp
    have "infinite_cts_filtration p M nat_filtration" using bernoulli_nat_filtration[of M p] bernoulli psgt pslt
      by simp
    thus "sets (G 0) = {{}, space M}" using stock_filtration
      infinite_cts_filtration.stoch_proc_filt_triv_init[of p M nat_filtration geom_proc]
      geom_rand_walk_borel_adapted bot_nat_def unfolding init_triv_filt_def by simp
    show "replicating_portfolio pf pyf matur" using pfprop .
    show "n. assetsupport_set pf. finite (prices Mkt asset n ` space M)"
    proof (intro allI ballI)
      fix n
      fix asset
      assume "asset  support_set pf"
      hence "prices Mkt asset n  borel_measurable (G n)" using readable pfprop
        unfolding  replicating_portfolio_def stock_portfolio_def adapt_stoch_proc_def by auto
      hence "prices Mkt asset n  borel_measurable (nat_filtration n)" using stock_filtration
        stoch_proc_subalg_nat_filt geom_rand_walk_borel_adapted
        measurable_from_subalg[of "nat_filtration n" "G n" "prices Mkt asset n" borel]
        unfolding adapt_stoch_proc_def by auto
      thus "finite (prices Mkt asset n ` space M)" using nat_filtration_vimage_finite[of "prices Mkt asset n"] by simp
    qed
    show "n. assetsupport_set pf. finite (pf asset n ` space M)"
    proof (intro allI ballI)
      fix n
      fix asset
      assume "asset  support_set pf"
      hence "pf asset n  borel_measurable (G n)" using pfprop predict_imp_adapt[of "pf asset"]
        unfolding replicating_portfolio_def trading_strategy_def adapt_stoch_proc_def by auto
      hence "pf asset n  borel_measurable (nat_filtration n)" using stock_filtration
        stoch_proc_subalg_nat_filt geom_rand_walk_borel_adapted
        measurable_from_subalg[of "nat_filtration n" "G n" "pf asset n" borel]
        unfolding adapt_stoch_proc_def by auto
      thus "finite (pf asset n ` space M)" using nat_filtration_vimage_finite[of "pf asset n"] by simp
    qed
  qed
  moreover have "integralL N dpf =
    ( w range (pseudo_proj_True matur). (prod (prob_component q w) {0..<matur}) * (dpf w))"
  proof (rule infinite_cts_filtration.expect_prob_comp)
    show "infinite_cts_filtration q N nat_filtration" using  assms  pslt psgt
        bernoulli_nat_filtration unfolding q_def using gt_param lt_param CRR_viable N_def by auto
    have "dpf  borel_measurable (G matur)" using assms discounted_measurable[of pyf "G matur"]
      unfolding dpf_def by simp
    thus "dpf  borel_measurable (nat_filtration matur)" using stock_filtration
        stoch_proc_subalg_nat_filt geom_rand_walk_borel_adapted
        measurable_from_subalg[of "nat_filtration matur" "G matur" dpf]
      unfolding adapt_stoch_proc_def by auto
  qed
  ultimately show ?thesis unfolding dpf_def q_def by simp
qed

end