Theory Down

section ‹ Down part ›

theory Down
imports Triangular_Function UpDown_Scheme
begin

lemma sparsegrid'_parents:
  assumes b: "b  sparsegrid' dm" and p': "p'  parents d b p"
  shows "p'  sparsegrid' dm"
  using assms parents_def sparsegrid'I by auto

lemma down'_β: " d < length b ; l + level b = lm ; b  sparsegrid' dm ; p  sparsegrid' dm  
  down' d l b fl fr α p = (if p  lgrid b {d} lm
  then
    (fl + (fr - fl) / 2 * (real_of_int (ix p d) / 2^(lv p d - lv b d) - real_of_int (ix b d) + 1)) / 2 ^ (lv p d + 1) +
    ( p'  parents d b p. (α p') * l2_φ (p ! d) (p' ! d))
  else α p)"
proof (induct l arbitrary: b α fl fr p)
  case (Suc l)

  let ?l = "child b left d" and ?r = "child b right d"
  let ?result = "((fl + fr) / 4 + (1 / 3) * (α b)) / 2 ^ (lv b d)"
  let ?fm = "(fl + fr) / 2 + (α b)"
  let ?down_l = "down' d l (child b left d) fl ?fm (α(b := ?result))"

  have "length b = dm" using b  sparsegrid' dm
    unfolding sparsegrid'_def start_def by auto
  hence "d < dm" using d < length b by auto

  have "!!dir. d < length (child b dir d)" using d < length b by auto
  have "!!dir. l + level (child b dir d) = lm"
    using d < length b and Suc l + level b = lm and child_level by auto
  have "!!dir. (child b dir d)  sparsegrid' dm"
    using b  sparsegrid' dm and d < dm and sparsegrid'_def by auto
  note hyps = Suc.hyps[OF !! dir. d < length (child b dir d)
    !!dir. l + level (child b dir d) = lm
    !!dir. (child b dir d)  sparsegrid' dm]

  show ?case
  proof (cases "p  lgrid b {d} lm")
    case False
    moreover hence "p  b" and "p  lgrid ?l {d} lm"
       and "p  lgrid ?r {d} lm" unfolding lgrid_def
      unfolding grid_partition[where p=b] using Suc l + level b = lm by auto
    ultimately show ?thesis
      unfolding down'.simps Let_def fun_upd_def hyps[OF p  sparsegrid' dm]
      by auto
  next
    case True hence "level p < lm" and "p  grid b {d}" unfolding lgrid_def by auto
    let ?lb = "lv b d"   and ?ib = "real_of_int (ix b d)"
    let ?lp   = "lv p d"  and ?ip   = "real_of_int (ix p d)"
    show ?thesis
    proof (cases " dir. p  grid (child b dir d){d}")
      case True
      obtain dir where p_grid: "p  grid (child b dir d) {d}" using True by auto
      hence "p  lgrid (child b dir d) {d} lm" using level p < lm unfolding lgrid_def by auto
      have "lv b d < lv p d" using child_lv[OF d < length b] and grid_single_level[OF p_grid d < length (child b dir d)] by auto

      let ?ch = "child b dir d"
      let ?ich = "child b (inv dir) d"

      show ?thesis
      proof (cases dir)
        case right
        hence "p  lgrid ?r {d} lm" and "p  grid ?r {d}"
          using p  grid ?ch {d} and level p < lm unfolding lgrid_def by auto

        { fix p' fix fl fr x assume p': "p'  parents d (child b right d) p"
          hence "p'  grid (child b right d) {d}" unfolding parents_def by simp
          hence "p'  lgrid (child b left d) {d} lm" and "p'  b"
            unfolding lgrid_def
            using grid_disjunct[OF d < length b] grid_not_child by auto

          from hyps[OF sparsegrid'_parents[OF child b right d  sparsegrid' dm
                       p']] this
          have "down' d l (child b left d) fl fr (α(b := x)) p' = α p'" by auto }
        thus  ?thesis
          unfolding down'.simps Let_def hyps[OF p  sparsegrid' dm]
            parent_sum[OF p  grid ?r {d} d < length b]
            l2_child[OF d < length b p  grid ?r {d}]
          using child_ix child_lv d < length b level_shift[OF lv b d < lv p d]
                sgn.simps p  lgrid b {d} lm p  lgrid ?r {d} lm
          by (auto simp add: algebra_simps diff_divide_distrib add_divide_distrib)
      next
        case left
        hence "p  lgrid ?l {d} lm" and "p  grid ?l {d}"
          using p  grid ?ch {d} and level p < lm unfolding lgrid_def by auto
        hence "¬ p  lgrid ?r {d} lm"
          using grid_disjunct[OF d < length b] unfolding lgrid_def by auto
        { fix p' assume p': "p'  parents d (child b left d) p"
          hence "p'  grid (child b left d) {d}" unfolding parents_def by simp
          hence "p'  b" using grid_not_child[OF d < length b] by auto }
        thus ?thesis
          unfolding down'.simps Let_def hyps[OF p  sparsegrid' dm]
                    parent_sum[OF p  grid ?l {d} d < length b]
                    l2_child[OF d < length b p  grid ?l {d}] sgn.simps
                    if_P[OF p  lgrid b {d} lm] if_P[OF p  lgrid ?l {d} lm]
                    if_not_P[OF p  lgrid ?r {d} lm]
          using child_ix child_lv d < length b level_shift[OF lv b d < lv p d]
          by (auto simp add: algebra_simps diff_divide_distrib add_divide_distrib)
      qed
    next
      case False hence not_child: "!! dir. ¬ p  grid (child b dir d) {d}" by auto
      hence "p = b" using grid_onedim_split[where ds="{}" and d=d and b=b] p  grid b {d} unfolding grid_empty_ds[where b=b] by auto
      from not_child have lnot_child: "!! dir. ¬ p  lgrid (child b dir d) {d} lm" unfolding lgrid_def by auto
      have result: "((fl + fr) / 4 + 1 / 3 * α b) / 2 ^ lv b d = (fl + (fr - fl) / 2) / 2 ^ (lv b d + 1) + α b * l2_φ (b ! d) (b ! d)"
        by (auto simp: l2_same diff_divide_distrib add_divide_distrib times_divide_eq_left[symmetric] algebra_simps)
      show ?thesis
        unfolding down'.simps Let_def fun_upd_def hyps[OF p  sparsegrid' dm] if_P[OF p  lgrid b {d} lm] if_not_P[OF lnot_child] if_P[OF p = b]
        unfolding p = b parents_single unfolding result by auto
    qed
  qed
next
  case 0
  have "p  lgrid b {d} lm"
  proof (rule ccontr)
    assume "¬ p  lgrid b {d} lm"
    hence "p  grid b {d}" and "level p < lm" unfolding lgrid_def by auto
    moreover from grid_level[OF p  grid b {d}] and 0 + level b = lm have "lm  level p" by auto
    ultimately show False by auto
  qed
  thus ?case unfolding down'.simps by auto
qed

lemma down: assumes "d < dm" and p: "p  sparsegrid dm lm"
  shows "(down dm lm d α) p = ( p'  parents d (base {d} p) p. (α p') * l2_φ (p ! d) (p' ! d))"
proof -
  let "?F d l p" = "down' d l p 0 0"
  let "?S x p p'" = "if p'  parents d (base {d} p) p then x * l2_φ (p ! d) (p' ! d) else 0"

  { fix p α assume "p  sparsegrid dm lm"
    from le_less_trans[OF grid_level sparsegridE(2)[OF this]]
    have "parents d (base {d} p) p   lgrid (base {d} p) {d} lm"
      unfolding lgrid_def parents_def by auto
    hence "(p'lgrid (base {d} p) {d} lm. ?S (α p') p p') =
      (p'parents d (base {d} p) p. α p' * l2_φ (p ! d) (p' ! d))"
      using lgrid_finite by (intro sum.mono_neutral_cong_right) auto
  } note sum_eq = this

  { fix l p b α
    assume b: "b  lgrid (start dm) ({0..<dm} - {d}) lm" and "l + level b = lm"
      and "p  sparsegrid dm lm"
    hence b_spg: "b  sparsegrid' dm" and p_spg: "p  sparsegrid' dm" and
      "d < length b" and "level p < lm"
      using sparsegrid'_start sparsegrid_subset d < dm by auto
    have "?F d l b α p = (if b = base {d} p then p'lgrid b {d} lm. ?S (α p') p p' else α p)"
    proof (cases "b = base {d} p")
      case True
      have "p  lgrid (base {d} p) {d} lm"
        using baseE(2)[OF p_spg] and level p < lm
        unfolding lgrid_def by auto
      thus ?thesis unfolding if_P[OF True]
        unfolding True sum_eq[OF p  sparsegrid dm lm]
        unfolding down'_β[OF d < length b l + level b = lm b_spg p_spg,
          unfolded True] by auto
    next
      case False
      have "p  lgrid b {d} lm"
      proof (rule ccontr)
        assume "¬ ?thesis" hence "p  grid b {d}" by auto
        from b this have "b = base {d} p" using baseI by auto
        thus False using False by simp
      qed
      thus ?thesis
        unfolding if_not_P[OF False]
        unfolding down'_β[OF d < length b l + level b = lm b_spg p_spg]
        by auto
    qed }
  from lift[OF d < dm p  sparsegrid dm lm, where F = ?F and S = ?S, OF this]
  show ?thesis
    unfolding down_def
    unfolding sum_eq[OF p] by simp
qed

end