[STATEMENT]
theorem mrbst_union_correct:
  assumes "finite A" "finite B"
  shows   "do {t1 \<leftarrow> random_bst A; t2 \<leftarrow> random_bst B; mrbst_union t1 t2} =
             random_bst (A \<union> B)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
from assms
[PROOF STATE]
proof (chain)
picking this:
finite A
finite B
[PROOF STEP]
have "finite (A \<union> B)"
[PROOF STATE]
proof (prove)
using this:
finite A
finite B

goal (1 subgoal):
 1. finite (A \<union> B)
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
finite (A \<union> B)

goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
thus ?thesis
[PROOF STATE]
proof (prove)
using this:
finite (A \<union> B)

goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
proof (induction "A \<union> B" arbitrary: A B rule: finite_psubset_induct)
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>A B. \<lbrakk>finite (A \<union> B); \<And>Aa Ba. Aa \<union> Ba \<subset> A \<union> B \<Longrightarrow> random_bst Aa \<bind> (\<lambda>t1. random_bst Ba \<bind> mrbst_union t1) = random_bst (Aa \<union> Ba)\<rbrakk> \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
case (psubset A B)
[PROOF STATE]
proof (state)
this:
finite (A \<union> B)
?A \<union> ?B \<subset> A \<union> B \<Longrightarrow> random_bst ?A \<bind> (\<lambda>t1. random_bst ?B \<bind> mrbst_union t1) = random_bst (?A \<union> ?B)

goal (1 subgoal):
 1. \<And>A B. \<lbrakk>finite (A \<union> B); \<And>Aa Ba. Aa \<union> Ba \<subset> A \<union> B \<Longrightarrow> random_bst Aa \<bind> (\<lambda>t1. random_bst Ba \<bind> mrbst_union t1) = random_bst (Aa \<union> Ba)\<rbrakk> \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
proof (cases "A = {} \<or> B = {}")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. A = {} \<or> B = {} \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
 2. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
A = {} \<or> B = {}

goal (2 subgoals):
 1. A = {} \<or> B = {} \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
 2. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
thus ?thesis
[PROOF STATE]
proof (prove)
using this:
A = {} \<or> B = {}

goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
including monad_normalisation
[PROOF STATE]
proof (prove)
using this:
A = {} \<or> B = {}

goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> (A = {} \<or> B = {})

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
with psubset.hyps
[PROOF STATE]
proof (chain)
picking this:
finite (A \<union> B)
?A \<union> ?B \<subset> A \<union> B \<Longrightarrow> random_bst ?A \<bind> (\<lambda>t1. random_bst ?B \<bind> mrbst_union t1) = random_bst (?A \<union> ?B)
\<not> (A = {} \<or> B = {})
[PROOF STEP]
have AB: "finite A" "finite B" "A \<noteq> {}" "B \<noteq> {}"
[PROOF STATE]
proof (prove)
using this:
finite (A \<union> B)
?A \<union> ?B \<subset> A \<union> B \<Longrightarrow> random_bst ?A \<bind> (\<lambda>t1. random_bst ?B \<bind> mrbst_union t1) = random_bst (?A \<union> ?B)
\<not> (A = {} \<or> B = {})

goal (1 subgoal):
 1. (finite A &&& finite B) &&& A \<noteq> {} &&& B \<noteq> {}
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
define m n l where "m = card A" and "n = card B" and "l = card (A \<inter> B)"
[PROOF STATE]
proof (state)
this:
m = card A
n = card B
l = card (A \<inter> B)

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
define p q where "p = m / (m + n)" and "q = l / n"
[PROOF STATE]
proof (state)
this:
p = real m / real (m + n)
q = real l / real n

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
define r where "r = p / (1 - (1 - p) * q)"
[PROOF STATE]
proof (state)
this:
r = p / (1 - (1 - p) * q)

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
from AB
[PROOF STATE]
proof (chain)
picking this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}
[PROOF STEP]
have mn: "m > 0" "n > 0"
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. 0 < m &&& 0 < n
[PROOF STEP]
by (auto simp: m_def n_def)
[PROOF STATE]
proof (state)
this:
0 < m
0 < n

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have pq: "p \<in> {0..1}" "q \<in> {0..1}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. p \<in> {0..1} &&& q \<in> {0..1}
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. p \<in> {0..1} &&& q \<in> {0..1}
[PROOF STEP]
by (auto simp: p_def q_def m_def n_def l_def divide_simps intro: card_mono)
[PROOF STATE]
proof (state)
this:
p \<in> {0..1}
q \<in> {0..1}

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
p \<in> {0..1}
q \<in> {0..1}

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "p \<noteq> 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. p \<noteq> 0
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. p \<noteq> 0
[PROOF STEP]
by (auto simp: p_def m_def n_def divide_simps add_nonneg_eq_0_iff)
[PROOF STATE]
proof (state)
this:
p \<noteq> 0

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
p \<in> {0..1}
q \<in> {0..1}
p \<noteq> 0
[PROOF STEP]
have "p > 0"
[PROOF STATE]
proof (prove)
using this:
p \<in> {0..1}
q \<in> {0..1}
p \<noteq> 0

goal (1 subgoal):
 1. 0 < p
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
0 < p

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "B - A = B - (A \<inter> B)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. B - A = B - A \<inter> B
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
B - A = B - A \<inter> B

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
B - A = B - A \<inter> B

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "card \<dots> = n - l"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. card (B - A \<inter> B) = n - l
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. card (B - A \<inter> B) = n - l
[PROOF STEP]
unfolding n_def l_def
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. card (B - A \<inter> B) = card B - card (A \<inter> B)
[PROOF STEP]
by (intro card_Diff_subset) auto
[PROOF STATE]
proof (state)
this:
card (B - A \<inter> B) = n - l

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
card (B - A) = n - l
[PROOF STEP]
have [simp]: "card (B - A) = n - l"
[PROOF STATE]
proof (prove)
using this:
card (B - A) = n - l

goal (1 subgoal):
 1. card (B - A) = n - l
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
card (B - A) = n - l

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
from AB
[PROOF STATE]
proof (chain)
picking this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}
[PROOF STEP]
have "l \<le> n"
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. l \<le> n
[PROOF STEP]
unfolding l_def n_def
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. card (A \<inter> B) \<le> card B
[PROOF STEP]
by (intro card_mono) auto
[PROOF STATE]
proof (state)
this:
l \<le> n

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "p \<le> 1 - (1 - p) * q"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. p \<le> 1 - (1 - p) * q
[PROOF STEP]
using mn \<open>l \<le> n\<close>
[PROOF STATE]
proof (prove)
using this:
0 < m
0 < n
l \<le> n

goal (1 subgoal):
 1. p \<le> 1 - (1 - p) * q
[PROOF STEP]
by (auto simp: p_def q_def divide_simps)
[PROOF STATE]
proof (state)
this:
p \<le> 1 - (1 - p) * q

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
hence r_aux: "(1 - p) * q \<in> {0..1 - p}"
[PROOF STATE]
proof (prove)
using this:
p \<le> 1 - (1 - p) * q

goal (1 subgoal):
 1. (1 - p) * q \<in> {0..1 - p}
[PROOF STEP]
using pq
[PROOF STATE]
proof (prove)
using this:
p \<le> 1 - (1 - p) * q
p \<in> {0..1}
q \<in> {0..1}

goal (1 subgoal):
 1. (1 - p) * q \<in> {0..1 - p}
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(1 - p) * q \<in> {0..1 - p}

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
include monad_normalisation
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
define RA1 RA2 RB1 RB2
        where "RA1 = (\<lambda>x. random_bst {z\<in>A. z < x})" and "RA2 = (\<lambda>x. random_bst {z\<in>A. z > x})"
          and "RB1 = (\<lambda>x. random_bst {z\<in>B. z < x})" and "RB2 = (\<lambda>x. random_bst {z\<in>B. z > x})"
[PROOF STATE]
proof (state)
this:
RA1 = (\<lambda>x. random_bst {z \<in> A. z < x})
RA2 = (\<lambda>x. random_bst {z \<in> A. x < z})
RB1 = (\<lambda>x. random_bst {z \<in> B. z < x})
RB2 = (\<lambda>x. random_bst {z \<in> B. x < z})

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "do {t1 \<leftarrow> random_bst A; t2 \<leftarrow> random_bst B; mrbst_union t1 t2} =
              do {
                x \<leftarrow> pmf_of_set A;
                l1 \<leftarrow> random_bst {z\<in>A. z < x};
                r1 \<leftarrow> random_bst {z\<in>A. z > x};
                y \<leftarrow> pmf_of_set B;
                l2 \<leftarrow> random_bst {z\<in>B. z < y};
                r2 \<leftarrow> random_bst {z\<in>B. z > y};
                let m = size \<langle>l1, x, r1\<rangle>;
                let n = size \<langle>l2, y, r2\<rangle>;
                b \<leftarrow> bernoulli_pmf (m / (m + n));
                if b then do {
                  l \<leftarrow> mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>));
                  r \<leftarrow> mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>));
                  return_pmf \<langle>l, x, r\<rangle>
                } else do {
                  l \<leftarrow> mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2;
                  r \<leftarrow> mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2;
                  if isin \<langle>l1, x, r1\<rangle> y then
                    mrbst_push_down l y r
                  else
                    return_pmf \<langle>l, y, r\<rangle>
                }
              }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))
[PROOF STEP]
by (simp add: random_bst_reduce split_bst'_altdef Let_def case_prod_unfold cong: if_cong)
[PROOF STATE]
proof (state)
this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        x \<leftarrow> pmf_of_set A;
                        l1 \<leftarrow> random_bst {z\<in>A. z < x};
                        r1 \<leftarrow> random_bst {z\<in>A. z > x};
                        y \<leftarrow> pmf_of_set B;
                        l2 \<leftarrow> random_bst {z\<in>B. z < y};
                        r2 \<leftarrow> random_bst {z\<in>B. z > y};
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          l \<leftarrow> mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>));
                          r \<leftarrow> mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>));
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          l \<leftarrow> mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2;
                          r \<leftarrow> mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2;
                          if y \<in> A then
                            mrbst_push_down l y r
                          else
                            return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))
[PROOF STEP]
unfolding Let_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf (real (size \<langle>l1, x, r1\<rangle>) / (real (size \<langle>l1, x, r1\<rangle>) + real (size \<langle>l2, y, r2\<rangle>))) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))
[PROOF STEP]
proof (intro bind_pmf_cong refl if_cong)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>x xa xb xc xd xe. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z})\<rbrakk> \<Longrightarrow> bernoulli_pmf (real (size \<langle>xa, x, xb\<rangle>) / (real (size \<langle>xa, x, xb\<rangle>) + real (size \<langle>xd, xc, xe\<rangle>))) = bernoulli_pmf p
 2. \<And>x xa xb xc xd xe xf xg xh. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z}); xf \<in> set_pmf (bernoulli_pmf p); \<not> xf; xg \<in> set_pmf (mrbst_union (fst (split_bst xc \<langle>xa, x, xb\<rangle>)) xd); xh \<in> set_pmf (mrbst_union (snd (split_bst xc \<langle>xa, x, xb\<rangle>)) xe)\<rbrakk> \<Longrightarrow> isin \<langle>xa, x, xb\<rangle> xc = (xc \<in> A)
[PROOF STEP]
fix l1 x r1 y
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>x xa xb xc xd xe. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z})\<rbrakk> \<Longrightarrow> bernoulli_pmf (real (size \<langle>xa, x, xb\<rangle>) / (real (size \<langle>xa, x, xb\<rangle>) + real (size \<langle>xd, xc, xe\<rangle>))) = bernoulli_pmf p
 2. \<And>x xa xb xc xd xe xf xg xh. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z}); xf \<in> set_pmf (bernoulli_pmf p); \<not> xf; xg \<in> set_pmf (mrbst_union (fst (split_bst xc \<langle>xa, x, xb\<rangle>)) xd); xh \<in> set_pmf (mrbst_union (snd (split_bst xc \<langle>xa, x, xb\<rangle>)) xe)\<rbrakk> \<Longrightarrow> isin \<langle>xa, x, xb\<rangle> xc = (xc \<in> A)
[PROOF STEP]
assume "l1 \<in> set_pmf (random_bst {z\<in>A. z < x})" "r1 \<in> set_pmf (random_bst {z\<in>A. z > x})"
               "x \<in> set_pmf (pmf_of_set A)"
[PROOF STATE]
proof (state)
this:
l1 \<in> set_pmf (random_bst {z \<in> A. z < x})
r1 \<in> set_pmf (random_bst {z \<in> A. x < z})
x \<in> set_pmf (pmf_of_set A)

goal (2 subgoals):
 1. \<And>x xa xb xc xd xe. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z})\<rbrakk> \<Longrightarrow> bernoulli_pmf (real (size \<langle>xa, x, xb\<rangle>) / (real (size \<langle>xa, x, xb\<rangle>) + real (size \<langle>xd, xc, xe\<rangle>))) = bernoulli_pmf p
 2. \<And>x xa xb xc xd xe xf xg xh. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z}); xf \<in> set_pmf (bernoulli_pmf p); \<not> xf; xg \<in> set_pmf (mrbst_union (fst (split_bst xc \<langle>xa, x, xb\<rangle>)) xd); xh \<in> set_pmf (mrbst_union (snd (split_bst xc \<langle>xa, x, xb\<rangle>)) xe)\<rbrakk> \<Longrightarrow> isin \<langle>xa, x, xb\<rangle> xc = (xc \<in> A)
[PROOF STEP]
thus "isin \<langle>l1, x, r1\<rangle> y \<longleftrightarrow> (y \<in> A)"
[PROOF STATE]
proof (prove)
using this:
l1 \<in> set_pmf (random_bst {z \<in> A. z < x})
r1 \<in> set_pmf (random_bst {z \<in> A. x < z})
x \<in> set_pmf (pmf_of_set A)

goal (1 subgoal):
 1. isin \<langle>l1, x, r1\<rangle> y = (y \<in> A)
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
l1 \<in> set_pmf (random_bst {z \<in> A. z < x})
r1 \<in> set_pmf (random_bst {z \<in> A. x < z})
x \<in> set_pmf (pmf_of_set A)
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. isin \<langle>l1, x, r1\<rangle> y = (y \<in> A)
[PROOF STEP]
by (subst isin_bst) (auto simp: bst_random_bst set_random_bst)
[PROOF STATE]
proof (state)
this:
isin \<langle>l1, x, r1\<rangle> y = (y \<in> A)

goal (1 subgoal):
 1. \<And>x xa xb xc xd xe. \<lbrakk>x \<in> set_pmf (pmf_of_set A); xa \<in> set_pmf (random_bst {z \<in> A. z < x}); xb \<in> set_pmf (random_bst {z \<in> A. x < z}); xc \<in> set_pmf (pmf_of_set B); xd \<in> set_pmf (random_bst {z \<in> B. z < xc}); xe \<in> set_pmf (random_bst {z \<in> B. xc < z})\<rbrakk> \<Longrightarrow> bernoulli_pmf (real (size \<langle>xa, x, xb\<rangle>) / (real (size \<langle>xa, x, xb\<rangle>) + real (size \<langle>xd, xc, xe\<rangle>))) = bernoulli_pmf p
[PROOF STEP]
qed (insert AB,
           auto simp: size_random_bst m_def n_def p_def isin_random_bst dest!: card_3way_split)
[PROOF STATE]
proof (state)
this:
pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. let xa = size \<langle>l1, x, r1\<rangle>; xb = size \<langle>l2, y, r2\<rangle> in bernoulli_pmf (real xa / (real xa + real xb)) \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if isin \<langle>l1, x, r1\<rangle> y then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          (l1, r1) \<leftarrow> pair_pmf (random_bst {z\<in>A. z < x}) (random_bst {z\<in>A. z > x});
                          (l2, r2) \<leftarrow> map_pmf (split_bst x) (random_bst B);
                          l \<leftarrow> mrbst_union l1 l2;
                          r \<leftarrow> mrbst_union r1 r2;
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          y \<leftarrow> pmf_of_set B;
                          (l1, r1) \<leftarrow> map_pmf (split_bst y) (random_bst A);
                          (l2, r2) \<leftarrow> pair_pmf (random_bst {z\<in>B. z < y}) (random_bst {z\<in>B. z > y});
                          l \<leftarrow> mrbst_union l1 l2;
                          r \<leftarrow> mrbst_union r1 r2;
                          if y \<in> A then
                            mrbst_push_down l y r
                          else
                            return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))
[PROOF STEP]
by (simp add: random_bst_reduce map_pmf_def case_prod_unfold pair_pmf_def cong: if_cong)
[PROOF STATE]
proof (state)
this:
pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> B. z < y} \<bind> (\<lambda>l2. random_bst {z \<in> B. y < z} \<bind> (\<lambda>r2. bernoulli_pmf p \<bind> (\<lambda>b. if b then mrbst_union l1 (fst (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>l. mrbst_union r1 (snd (split_bst x \<langle>l2, y, r2\<rangle>)) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>)) else mrbst_union (fst (split_bst y \<langle>l1, x, r1\<rangle>)) l2 \<bind> (\<lambda>l. mrbst_union (snd (split_bst y \<langle>l1, x, r1\<rangle>)) r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          (l1, r1) \<leftarrow> pair_pmf (RA1 x) (RA2 x);
                          (l2, r2) \<leftarrow> pair_pmf (RB1 x) (RB2 x);
                          l \<leftarrow> mrbst_union l1 l2;
                          r \<leftarrow> mrbst_union r1 r2;
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          y \<leftarrow> pmf_of_set B;
                          (l1, r1) \<leftarrow> pair_pmf (RA1 y) (RA2 y);
                          (l2, r2) \<leftarrow> pair_pmf (RB1 y) (RB2 y);
                          l \<leftarrow> mrbst_union l1 l2;
                          r \<leftarrow> mrbst_union r1 r2;
                          if y \<in> A then
                            mrbst_push_down l y r
                          else
                            return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (RA1 x) (RA2 x) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 x) (RB2 x) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (RA1 y) (RA2 y) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 y) (RB2 y) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))
[PROOF STEP]
unfolding case_prod_unfold RA1_def RA2_def RB1_def RB2_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>p. map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>pa. mrbst_union (fst p) (fst pa) \<bind> (\<lambda>l. mrbst_union (snd p) (snd pa) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>p. pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>pa. mrbst_union (fst p) (fst pa) \<bind> (\<lambda>l. mrbst_union (snd p) (snd pa) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>p. pair_pmf (random_bst {z \<in> B. z < x}) (random_bst {z \<in> B. x < z}) \<bind> (\<lambda>pa. mrbst_union (fst p) (fst pa) \<bind> (\<lambda>l. mrbst_union (snd p) (snd pa) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (random_bst {z \<in> A. z < y}) (random_bst {z \<in> A. y < z}) \<bind> (\<lambda>p. pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>pa. mrbst_union (fst p) (fst pa) \<bind> (\<lambda>l. mrbst_union (snd p) (snd pa) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))
[PROOF STEP]
by (intro bind_pmf_cong refl if_cong split_random_bst AB)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (RA1 x) (RA2 x) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 x) (RB2 x) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (RA1 y) (RA2 y) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 y) (RB2 y) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (random_bst {z \<in> A. z < x}) (random_bst {z \<in> A. x < z}) \<bind> (\<lambda>(l1, r1). map_pmf (split_bst x) (random_bst B) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. map_pmf (split_bst y) (random_bst A) \<bind> (\<lambda>(l1, r1). pair_pmf (random_bst {z \<in> B. z < y}) (random_bst {z \<in> B. y < z}) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (RA1 x) (RA2 x) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 x) (RB2 x) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (RA1 y) (RA2 y) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 y) (RB2 y) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          l \<leftarrow> do {l1 \<leftarrow> RA1 x; l2 \<leftarrow> RB1 x; mrbst_union l1 l2};
                          r \<leftarrow> do {r1 \<leftarrow> RA2 x; r2 \<leftarrow> RB2 x; mrbst_union r1 r2};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          y \<leftarrow> pmf_of_set B;
                          l \<leftarrow> do {l1 \<leftarrow> RA1 y; l2 \<leftarrow> RB1 y; mrbst_union l1 l2};
                          r \<leftarrow> do {r1 \<leftarrow> RA2 y; r2 \<leftarrow> RB2 y; mrbst_union r1 r2};
                          if y \<in> A then
                            mrbst_push_down l y r
                          else
                            return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (RA1 x) (RA2 x) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 x) (RB2 x) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (RA1 y) (RA2 y) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 y) (RB2 y) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. RA1 x \<bind> (\<lambda>l1. RB1 x \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 x \<bind> (\<lambda>r1. RB2 x \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. RA1 y \<bind> (\<lambda>l1. RB1 y \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 y \<bind> (\<lambda>r1. RB2 y \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
by (simp add: pair_pmf_def cong: if_cong)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (RA1 x) (RA2 x) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 x) (RB2 x) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (RA1 y) (RA2 y) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 y) (RB2 y) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. RA1 x \<bind> (\<lambda>l1. RB1 x \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 x \<bind> (\<lambda>r1. RB2 x \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. RA1 y \<bind> (\<lambda>l1. RB1 y \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 y \<bind> (\<lambda>r1. RB2 y \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. pair_pmf (RA1 x) (RA2 x) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 x) (RB2 x) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))))) else pmf_of_set B \<bind> (\<lambda>y. pair_pmf (RA1 y) (RA2 y) \<bind> (\<lambda>(l1, r1). pair_pmf (RB1 y) (RB2 y) \<bind> (\<lambda>(l2, r2). mrbst_union l1 l2 \<bind> (\<lambda>l. mrbst_union r1 r2 \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. RA1 x \<bind> (\<lambda>l1. RB1 x \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 x \<bind> (\<lambda>r1. RB2 x \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. RA1 y \<bind> (\<lambda>l1. RB1 y \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 y \<bind> (\<lambda>r1. RB2 y \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          l \<leftarrow> random_bst ({z\<in>A. z < x} \<union> {z\<in>B. z < x});
                          r \<leftarrow> random_bst ({z\<in>A. z > x} \<union> {z\<in>B. z > x});
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          y \<leftarrow> pmf_of_set B;
                          l \<leftarrow> random_bst ({z\<in>A. z < y} \<union> {z\<in>B. z < y});
                          r \<leftarrow> random_bst ({z\<in>A. z > y} \<union> {z\<in>B. z > y});
                          if y \<in> A then
                            mrbst_push_down l y r
                          else
                            return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. RA1 x \<bind> (\<lambda>l1. RB1 x \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 x \<bind> (\<lambda>r1. RB2 x \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. RA1 y \<bind> (\<lambda>l1. RB1 y \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 y \<bind> (\<lambda>r1. RB2 y \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
unfolding RA1_def RA2_def RB1_def RB2_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> B. z < x} \<bind> mrbst_union l1) \<bind> (\<lambda>l. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. random_bst {z \<in> B. x < z} \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A. z < y} \<bind> (\<lambda>l1. random_bst {z \<in> B. z < y} \<bind> mrbst_union l1) \<bind> (\<lambda>l. random_bst {z \<in> A. y < z} \<bind> (\<lambda>r1. random_bst {z \<in> B. y < z} \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A. z < x} \<bind> (\<lambda>l1. random_bst {z \<in> B. z < x} \<bind> mrbst_union l1) \<bind> (\<lambda>l. random_bst {z \<in> A. x < z} \<bind> (\<lambda>r1. random_bst {z \<in> B. x < z} \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A. z < y} \<bind> (\<lambda>l1. random_bst {z \<in> B. z < y} \<bind> mrbst_union l1) \<bind> (\<lambda>l. random_bst {z \<in> A. y < z} \<bind> (\<lambda>r1. random_bst {z \<in> B. y < z} \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
by (intro bind_pmf_cong if_cong refl psubset) auto
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. RA1 x \<bind> (\<lambda>l1. RB1 x \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 x \<bind> (\<lambda>r1. RB2 x \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. RA1 y \<bind> (\<lambda>l1. RB1 y \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 y \<bind> (\<lambda>r1. RB2 y \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. RA1 x \<bind> (\<lambda>l1. RB1 x \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 x \<bind> (\<lambda>r1. RB2 x \<bind> mrbst_union r1) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. RA1 y \<bind> (\<lambda>l1. RB1 y \<bind> mrbst_union l1) \<bind> (\<lambda>l. RA2 y \<bind> (\<lambda>r1. RB2 y \<bind> mrbst_union r1) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          y \<leftarrow> pmf_of_set B;
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                          if y \<in> A then
                            mrbst_push_down l y r
                          else
                            return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
by (intro bind_pmf_cong if_cong refl arg_cong[of _ _ random_bst]) auto
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst ({z \<in> A. z < x} \<union> {z \<in> B. z < x}) \<bind> (\<lambda>l. random_bst ({z \<in> A. x < z} \<union> {z \<in> B. x < z}) \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst ({z \<in> A. z < y} \<union> {z \<in> B. z < y}) \<bind> (\<lambda>l. random_bst ({z \<in> A. y < z} \<union> {z \<in> B. y < z}) \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          b' \<leftarrow> bernoulli_pmf q;
                          if b' then do {
                            y \<leftarrow> pmf_of_set (A \<inter> B);
                            random_bst (A \<union> B)
                          } else do {
                            y \<leftarrow> pmf_of_set (B - A);
                            l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                            r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                            return_pmf \<langle>l, y, r\<rangle>
                          }
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))))
[PROOF STEP]
proof (intro bind_pmf_cong refl if_cong, goal_cases)
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
case (1 b)
[PROOF STATE]
proof (state)
this:
b \<in> set_pmf (bernoulli_pmf p)
\<not> b

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
have q_pos: "A \<inter> B \<noteq> {}" if "q > 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. A \<inter> B \<noteq> {}
[PROOF STEP]
using that
[PROOF STATE]
proof (prove)
using this:
0 < q

goal (1 subgoal):
 1. A \<inter> B \<noteq> {}
[PROOF STEP]
by (auto simp: q_def l_def)
[PROOF STATE]
proof (state)
this:
0 < q \<Longrightarrow> A \<inter> B \<noteq> {}

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
have q_lt1: "B - A \<noteq> {}" if "q < 1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. B - A \<noteq> {}
[PROOF STEP]
proof
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. B - A = {} \<Longrightarrow> False
[PROOF STEP]
assume "B - A = {}"
[PROOF STATE]
proof (state)
this:
B - A = {}

goal (1 subgoal):
 1. B - A = {} \<Longrightarrow> False
[PROOF STEP]
hence "A \<inter> B = B"
[PROOF STATE]
proof (prove)
using this:
B - A = {}

goal (1 subgoal):
 1. A \<inter> B = B
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
A \<inter> B = B

goal (1 subgoal):
 1. B - A = {} \<Longrightarrow> False
[PROOF STEP]
thus False
[PROOF STATE]
proof (prove)
using this:
A \<inter> B = B

goal (1 subgoal):
 1. False
[PROOF STEP]
using that AB
[PROOF STATE]
proof (prove)
using this:
A \<inter> B = B
q < 1
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. False
[PROOF STEP]
by (auto simp: q_def l_def n_def)
[PROOF STATE]
proof (state)
this:
False

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
q < 1 \<Longrightarrow> B - A \<noteq> {}

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
have eq: "pmf_of_set B = do {b' \<leftarrow> bernoulli_pmf q;
                                     if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. pmf_of_set B = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A))
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. pmf_of_set B = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A))
[PROOF STEP]
by (intro pmf_of_set_split_inter_diff [symmetric])
                      (auto simp: q_def l_def n_def)
[PROOF STATE]
proof (state)
this:
pmf_of_set B = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A))

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
have "do {y \<leftarrow> pmf_of_set B;
                  l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                  r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                  if y \<in> A then
                    mrbst_push_down l y r
                  else
                    return_pmf \<langle>l, y, r\<rangle>
                 } =
              do {
                b' \<leftarrow> bernoulli_pmf q;
                y \<leftarrow> (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A));
                l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                if b' then
                  mrbst_push_down l y r
                else
                  return_pmf \<langle>l, y, r\<rangle>
              }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
unfolding eq bind_assoc_pmf
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf q \<bind> (\<lambda>x. (if x then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
using AB q_pos q_lt1
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}
0 < q \<Longrightarrow> A \<inter> B \<noteq> {}
q < 1 \<Longrightarrow> B - A \<noteq> {}

goal (1 subgoal):
 1. bernoulli_pmf q \<bind> (\<lambda>x. (if x then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
by (intro bind_pmf_cong refl if_cong) (auto split: if_splits)
[PROOF STATE]
proof (state)
this:
pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
have "\<dots> = do {
                          b' \<leftarrow> bernoulli_pmf q;
                          if b' then do {
                            y \<leftarrow> pmf_of_set (A \<inter> B);
                            do {l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                                r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                                mrbst_push_down l y r}
                          } else do {
                            y \<leftarrow> pmf_of_set (B - A);
                            l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                            r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                            return_pmf \<langle>l, y, r\<rangle>
                          }
                        }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> mrbst_push_down l y)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
by (simp cong: if_cong)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> mrbst_push_down l y)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf q \<bind> (\<lambda>b'. (if b' then pmf_of_set (A \<inter> B) else pmf_of_set (B - A)) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if b' then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> mrbst_push_down l y)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
have "\<dots> = do {
                          b' \<leftarrow> bernoulli_pmf q;
                          if b' then do {
                            y \<leftarrow> pmf_of_set (A \<inter> B);
                            random_bst (A \<union> B)
                          } else do {
                            y \<leftarrow> pmf_of_set (B - A);
                            l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                            r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                            return_pmf \<langle>l, y, r\<rangle>
                          }
                        }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> mrbst_push_down l y)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
using AB q_pos
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}
0 < q \<Longrightarrow> A \<inter> B \<noteq> {}

goal (1 subgoal):
 1. bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> mrbst_push_down l y)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
by (intro bind_pmf_cong if_cong refl mrbst_push_down_correct') auto
[PROOF STATE]
proof (state)
this:
bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> mrbst_push_down l y)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> set_pmf (bernoulli_pmf p); \<not> x\<rbrakk> \<Longrightarrow> pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
using this:
pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))

goal (1 subgoal):
 1. pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>))) = bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else pmf_of_set B \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. if y \<in> A then mrbst_push_down l y r else return_pmf \<langle>l, y, r\<rangle>)))) = bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf p;
                        b' \<leftarrow> bernoulli_pmf q;
                        if b then do {
                          x \<leftarrow> pmf_of_set A;
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else if b' then do {
                            random_bst (A \<union> B)
                        } else do {
                          y \<leftarrow> pmf_of_set (B - A);
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < y};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > y};
                          return_pmf \<langle>l, y, r\<rangle>
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))))
[PROOF STEP]
by (simp cong: if_cong)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else bernoulli_pmf q \<bind> (\<lambda>b'. if b' then pmf_of_set (A \<inter> B) \<bind> (\<lambda>y. random_bst (A \<union> B)) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>)))))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        (b, b') \<leftarrow> pair_pmf (bernoulli_pmf p) (bernoulli_pmf q);
                        if b \<or> \<not>b' then do {
                          x \<leftarrow> (if b then pmf_of_set A else pmf_of_set (B - A));
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                            random_bst (A \<union> B)
                        }
                      }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = pair_pmf (bernoulli_pmf p) (bernoulli_pmf q) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))
[PROOF STEP]
unfolding pair_pmf_def bind_assoc_pmf
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = bernoulli_pmf p \<bind> (\<lambda>x. bernoulli_pmf q \<bind> (\<lambda>xa. return_pmf (x, xa) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))))
[PROOF STEP]
by (intro bind_pmf_cong) auto
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = pair_pmf (bernoulli_pmf p) (bernoulli_pmf q) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf p \<bind> (\<lambda>b. bernoulli_pmf q \<bind> (\<lambda>b'. if b then pmf_of_set A \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else if b' then random_bst (A \<union> B) else pmf_of_set (B - A) \<bind> (\<lambda>y. random_bst {z \<in> A \<union> B. z < y} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. y < z} \<bind> (\<lambda>r. return_pmf \<langle>l, y, r\<rangle>))))) = pair_pmf (bernoulli_pmf p) (bernoulli_pmf q) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        (b, b') \<leftarrow> map_pmf (\<lambda>(b, b'). (b \<or> \<not>b', b))
                                    (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q));
                        if b then do {
                          x \<leftarrow> (if b' then pmf_of_set A else pmf_of_set (B - A));
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                            random_bst (A \<union> B)
                        }
                      }" (is "_ = bind_pmf _ ?f")
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. pair_pmf (bernoulli_pmf p) (bernoulli_pmf q) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) \<bind> (\<lambda>(b, b'). if b then (if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))
[PROOF STEP]
by (simp add: bind_map_pmf case_prod_unfold cong: if_cong)
[PROOF STATE]
proof (state)
this:
pair_pmf (bernoulli_pmf p) (bernoulli_pmf q) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) \<bind> (\<lambda>(b, b'). if b then (if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
pair_pmf (bernoulli_pmf p) (bernoulli_pmf q) \<bind> (\<lambda>(b, b'). if b \<or> \<not> b' then (if b then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) \<bind> (\<lambda>(b, b'). if b then (if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "map_pmf (\<lambda>(b, b'). (b \<or> \<not>b', b))
                   (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) =
                 do {
                   b \<leftarrow> bernoulli_pmf (1 - (1 - p) * q);
                   b' \<leftarrow> (if b then bernoulli_pmf r else return_pmf False);
                   return_pmf (b, b')
                 }" (is "?lhs = ?rhs")
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))
[PROOF STEP]
proof (intro pmf_eqI)
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>i. pmf (map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q))) i = pmf (bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))) i
[PROOF STEP]
fix bb' :: "bool \<times> bool"
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>i. pmf (map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q))) i = pmf (bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))) i
[PROOF STEP]
obtain b b' where [simp]: "bb' = (b, b')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>b b'. bb' = (b, b') \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by (cases bb')
[PROOF STATE]
proof (state)
this:
bb' = (b, b')

goal (1 subgoal):
 1. \<And>i. pmf (map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q))) i = pmf (bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))) i
[PROOF STEP]
thus "pmf ?lhs bb' = pmf ?rhs bb'"
[PROOF STATE]
proof (prove)
using this:
bb' = (b, b')

goal (1 subgoal):
 1. pmf (map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q))) bb' = pmf (bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))) bb'
[PROOF STEP]
using pq r_aux \<open>p > 0\<close>
[PROOF STATE]
proof (prove)
using this:
bb' = (b, b')
p \<in> {0..1}
q \<in> {0..1}
(1 - p) * q \<in> {0..1 - p}
0 < p

goal (1 subgoal):
 1. pmf (map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q))) bb' = pmf (bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))) bb'
[PROOF STEP]
by (cases b; cases b')
             (auto simp: pmf_map pmf_bind_bernoulli measure_measure_pmf_finite
                         vimage_bool_pair pmf_pair r_def field_simps)
[PROOF STATE]
proof (state)
this:
pmf (map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q))) bb' = pmf (bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))) bb'

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
map_pmf (\<lambda>(b, b'). (b \<or> \<not> b', b)) (pair_pmf (bernoulli_pmf p) (bernoulli_pmf q)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b')))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> \<bind> ?f = do {
                              b \<leftarrow> bernoulli_pmf (1 - (1 - p) * q);
                              if b then do {
                                x \<leftarrow> do {b' \<leftarrow> bernoulli_pmf r;
                                         if b' then pmf_of_set A else pmf_of_set (B - A)};
                                l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                                r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                                return_pmf \<langle>l, x, r\<rangle>
                              } else do {
                                random_bst (A \<union> B)
                              }
                            }"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b'))) \<bind> (\<lambda>(b, b'). if b then (if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))
[PROOF STEP]
by (simp cong: if_cong)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b'))) \<bind> (\<lambda>(b, b'). if b then (if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. (if b then bernoulli_pmf r else return_pmf False) \<bind> (\<lambda>b'. return_pmf (b, b'))) \<bind> (\<lambda>(b, b'). if b then (if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "\<dots> = do {
                        b \<leftarrow> bernoulli_pmf (1 - (1 - p) * q);
                        if b then do {
                          x \<leftarrow> pmf_of_set (A \<union> (B - A));
                          l \<leftarrow> random_bst {z\<in>A \<union> B. z < x};
                          r \<leftarrow> random_bst {z\<in>A \<union> B. z > x};
                          return_pmf \<langle>l, x, r\<rangle>
                        } else do {
                          random_bst (A \<union> B)
                        }
                      }" (is "_ = ?f (A \<union> (B - A))")
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))
[PROOF STEP]
using AB pq \<open>l \<le> n\<close> mn
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}
p \<in> {0..1}
q \<in> {0..1}
l \<le> n
0 < m
0 < n

goal (1 subgoal):
 1. bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))
[PROOF STEP]
by (intro bind_pmf_cong if_cong refl pmf_of_set_union_split)
           (auto simp: m_def [symmetric] n_def [symmetric] r_def p_def q_def divide_simps)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then bernoulli_pmf r \<bind> (\<lambda>b'. if b' then pmf_of_set A else pmf_of_set (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> (B - A)) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B))

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "A \<union> (B - A) = A \<union> B"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. A \<union> (B - A) = A \<union> B
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
A \<union> (B - A) = A \<union> B

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
A \<union> (B - A) = A \<union> B

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
have "?f \<dots> = random_bst (A \<union> B)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> B) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = random_bst (A \<union> B)
[PROOF STEP]
using AB
[PROOF STATE]
proof (prove)
using this:
finite A
finite B
A \<noteq> {}
B \<noteq> {}

goal (1 subgoal):
 1. bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> B) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = random_bst (A \<union> B)
[PROOF STEP]
by (simp add: random_bst_reduce cong: if_cong)
[PROOF STATE]
proof (state)
this:
bernoulli_pmf (1 - (1 - p) * q) \<bind> (\<lambda>b. if b then pmf_of_set (A \<union> B) \<bind> (\<lambda>x. random_bst {z \<in> A \<union> B. z < x} \<bind> (\<lambda>l. random_bst {z \<in> A \<union> B. x < z} \<bind> (\<lambda>r. return_pmf \<langle>l, x, r\<rangle>))) else random_bst (A \<union> B)) = random_bst (A \<union> B)

goal (1 subgoal):
 1. \<not> (A = {} \<or> B = {}) \<Longrightarrow> random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)

goal (1 subgoal):
 1. random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
random_bst A \<bind> (\<lambda>t1. random_bst B \<bind> mrbst_union t1) = random_bst (A \<union> B)

goal:
No subgoals!
[PROOF STEP]
qed