[STATEMENT]
lemma get_prefix_of_separating_sequence_result :
  fixes M1 :: "('a::linorder,'b::linorder,'c::linorder) fsm"
  assumes "observable M1"
  and     "observable M2"
  and     "minimal M1"
  and     "u \<in> L M1" and "u \<in> L M2"
  and     "v \<in> L M1" and "v \<in> L M2"
  and     "after_initial M1 u \<noteq> after_initial M1 v"
  and     "\<And> \<alpha> \<beta> q1 q2 . q1 \<in> states M1 \<Longrightarrow> q2 \<in> states M1 \<Longrightarrow> q1 \<noteq> q2 \<Longrightarrow> distinguishes M1 q1 q2 (get_distinguishing_trace q1 q2)"
  and     "convergence_graph_lookup_invar M1 M2 cg_lookup G"
  and     "L M1 \<inter> set T = L M2 \<inter> set T"
shows "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v"
and   "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow>  \<exists> \<gamma> . distinguishes M1 (after_initial M1 u) (after_initial M1 v) ((snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))@\<gamma>)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v) &&& (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v
 2. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)
[PROOF STEP]
have "(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v)
        \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow>  (\<exists> \<gamma> . distinguishes M1 (after_initial M1 u) (after_initial M1 v) ((snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))@\<gamma>)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)))
[PROOF STEP]
using assms(4,5,6,7,8)
[PROOF STATE]
proof (prove)
using this:
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v

goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)))
[PROOF STEP]
proof (induction k arbitrary: u v)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) @ \<gamma>)))
 2. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
case 0
[PROOF STATE]
proof (state)
this:
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v

goal (2 subgoals):
 1. \<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) @ \<gamma>)))
 2. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v
[PROOF STEP]
have "\<exists> \<gamma> . distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>"
[PROOF STATE]
proof (prove)
using this:
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v

goal (1 subgoal):
 1. \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>
[PROOF STEP]
using \<open>minimal M1\<close>
[PROOF STATE]
proof (prove)
using this:
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v
minimal M1

goal (1 subgoal):
 1. \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>
[PROOF STEP]
unfolding minimal.simps
[PROOF STATE]
proof (prove)
using this:
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v
\<forall>q\<in>FSM.states M1. \<forall>q'\<in>FSM.states M1. q \<noteq> q' \<longrightarrow> LS M1 q \<noteq> LS M1 q'

goal (1 subgoal):
 1. \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>
[PROOF STEP]
by (meson after_is_state assms(1) assms(9))
[PROOF STATE]
proof (state)
this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>

goal (2 subgoals):
 1. \<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) @ \<gamma>)))
 2. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
using this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>

goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) @ \<gamma>)))
[PROOF STEP]
unfolding get_prefix_of_separating_sequence.simps fst_conv snd_conv
[PROOF STATE]
proof (prove)
using this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) \<gamma>

goal (1 subgoal):
 1. (1 = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (1 \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([] @ \<gamma>)))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v 0) @ \<gamma>)))

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
case (Suc k)
[PROOF STATE]
proof (state)
this:
\<lbrakk>?u \<in> L M1; ?u \<in> L M2; ?v \<in> L M1; ?v \<in> L M2; after_initial M1 ?u \<noteq> after_initial M1 ?v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace ?u ?v k) = 0 \<longrightarrow> \<not> converge M2 ?u ?v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace ?u ?v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 ?u) (after_initial M1 ?v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace ?u ?v k) @ \<gamma>)))
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define u' where u': "u' = shortest_list_or_default (cg_lookup G u) u"
[PROOF STATE]
proof (state)
this:
u' = shortest_list_or_default (cg_lookup G u) u

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define v' where v': "v' = shortest_list_or_default (cg_lookup G v) v"
[PROOF STATE]
proof (state)
this:
v' = shortest_list_or_default (cg_lookup G v) v

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define su where su: "su = after_initial M1 u"
[PROOF STATE]
proof (state)
this:
su = after_initial M1 u

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define sv where sv: "sv = after_initial M1 v"
[PROOF STATE]
proof (state)
this:
sv = after_initial M1 v

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define bestPrefix0 where bestPrefix0: "bestPrefix0 = get_distinguishing_trace su sv"
[PROOF STATE]
proof (state)
this:
bestPrefix0 = get_distinguishing_trace su sv

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define minEst0 where minEst0: "minEst0 = length bestPrefix0 + (if (has_leaf T G cg_lookup u') then 0 else length u') + (if (has_leaf T G cg_lookup v') then 0 else length v')"
[PROOF STATE]
proof (state)
this:
minEst0 = length bestPrefix0 + (if has_leaf T G cg_lookup u' then 0 else length u') + (if has_leaf T G cg_lookup v' then 0 else length v')

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define errorValue where errorValue: "errorValue = Suc minEst0"
[PROOF STATE]
proof (state)
this:
errorValue = Suc minEst0

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define XY where XY: "XY = List.product (inputs_as_list M1) (outputs_as_list M1)"
[PROOF STATE]
proof (state)
this:
XY = List.product (inputs_as_list M1) (outputs_as_list M1)

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define tryIO where tryIO: "tryIO = (\<lambda> (minEst,bestPrefix) (x,y) .
              if minEst = 0
                then (minEst,bestPrefix)
                else (case get_extension T G cg_lookup u' x y of
                      Some u'' \<Rightarrow> (case get_extension T G cg_lookup v' x y of
                        Some v'' \<Rightarrow> if (h_obs M1 su x y = None) \<noteq> (h_obs M1 sv x y = None)
                          then (0,[])
                          else if h_obs M1 su x y = h_obs M1 sv x y
                            then (minEst,bestPrefix)
                            else (let (e,w) = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u''@[(x,y)]) (v''@[(x,y)]) k
                                    in if e = 0
                                      then (0,[])
                                      else if e \<le> minEst
                                        then (e,(x,y)#w)
                                        else (minEst,bestPrefix)) |
                        None \<Rightarrow> (let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue;
                                  e' = if e \<noteq> 1
                                        then if has_leaf T G cg_lookup u''
                                          then e + 1
                                          else if \<not>(has_leaf T G cg_lookup (u''@[(x,y)]))
                                            then e + length u' + 1
                                            else e
                                        else e;
                                  e'' = e' + (if \<not>(has_leaf T G cg_lookup v') then length v' else 0)
                                in if e'' \<le> minEst
                                  then (e'',[(x,y)])
                                  else (minEst,bestPrefix))) |
                      None \<Rightarrow> (case get_extension T G cg_lookup v' x y of
                        Some v'' \<Rightarrow> (let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue;
                                  e' = if e \<noteq> 1
                                        then if has_leaf T G cg_lookup v''
                                          then e + 1
                                          else if \<not>(has_leaf T G cg_lookup (v''@[(x,y)]))
                                            then e + length v' + 1
                                            else e
                                        else e;
                                  e'' = e' + (if \<not>(has_leaf T G cg_lookup u') then length u' else 0)
                                in if e'' \<le> minEst
                                  then (e'',[(x,y)])
                                  else (minEst,bestPrefix)) |
                        None \<Rightarrow> (minEst,bestPrefix))))"
[PROOF STATE]
proof (state)
this:
tryIO = (\<lambda>(minEst, bestPrefix) (x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if e \<noteq> 1 then if has_leaf T G cg_lookup v'' then e + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then e + length v' + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if e \<noteq> 1 then if has_leaf T G cg_lookup u'' then e + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then e + length u' + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else let (e, w) = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k in if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix))

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have res': "(get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) =
                  (if \<not> isin T u' \<or> \<not> isin T v' then (errorValue,[]) else foldl tryIO (minEst0,[]) XY)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (if \<not> isin T u' \<or> \<not> isin T v' then (errorValue, []) else foldl tryIO (minEst0, []) XY)
[PROOF STEP]
unfolding tryIO XY errorValue minEst0 bestPrefix0 sv su v' u'
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (if \<not> isin T (shortest_list_or_default (cg_lookup G u) u) \<or> \<not> isin T (shortest_list_or_default (cg_lookup G v) v) then (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))), []) else foldl (\<lambda>(minEst, bestPrefix) (x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) x y of None \<Rightarrow> case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))); e' = if e \<noteq> 1 then if has_leaf T G cg_lookup v'' then e + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then e + length (shortest_list_or_default (cg_lookup G v) v) + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then length (shortest_list_or_default (cg_lookup G u) u) else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) x y of None \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))); e' = if e \<noteq> 1 then if has_leaf T G cg_lookup u'' then e + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then e + length (shortest_list_or_default (cg_lookup G u) u) + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then length (shortest_list_or_default (cg_lookup G v) v) else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 (after_initial M1 u) x y = None) \<noteq> (FSM.h_obs M1 (after_initial M1 v) x y = None) then (0, []) else if FSM.h_obs M1 (after_initial M1 u) x y = FSM.h_obs M1 (after_initial M1 v) x y then (minEst, bestPrefix) else let (e, w) = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k in if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)), []) (List.product (inputs_as_list M1) (outputs_as_list M1)))
[PROOF STEP]
unfolding get_prefix_of_separating_sequence.simps Let_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (if \<not> isin T (shortest_list_or_default (cg_lookup G u) u) \<or> \<not> isin T (shortest_list_or_default (cg_lookup G v) v) then (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))), []) else foldl (\<lambda>(minEst, bestPrefix) (x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) x y of None \<Rightarrow> case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G v) v) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then length (shortest_list_or_default (cg_lookup G u) u) else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G v) v) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then length (shortest_list_or_default (cg_lookup G u) u) else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G u) u) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then length (shortest_list_or_default (cg_lookup G v) v) else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G u) u) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then length (shortest_list_or_default (cg_lookup G v) v) else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 (after_initial M1 u) x y = None) \<noteq> (FSM.h_obs M1 (after_initial M1 v) x y = None) then (0, []) else if FSM.h_obs M1 (after_initial M1 u) x y = FSM.h_obs M1 (after_initial M1 v) x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)), []) (List.product (inputs_as_list M1) (outputs_as_list M1))) = (if \<not> isin T (shortest_list_or_default (cg_lookup G u) u) \<or> \<not> isin T (shortest_list_or_default (cg_lookup G v) v) then (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))), []) else foldl (\<lambda>(minEst, bestPrefix) (x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) x y of None \<Rightarrow> case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G v) v) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then length (shortest_list_or_default (cg_lookup G u) u) else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G v) v) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then length (shortest_list_or_default (cg_lookup G u) u) else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G u) u) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then length (shortest_list_or_default (cg_lookup G v) v) else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) + length (shortest_list_or_default (cg_lookup G u) u) + 1 else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)))) else estimate_growth M1 get_distinguishing_trace (after_initial M1 u) (after_initial M1 v) x y (Suc (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v))))) + (if \<not> has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then length (shortest_list_or_default (cg_lookup G v) v) else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 (after_initial M1 u) x y = None) \<noteq> (FSM.h_obs M1 (after_initial M1 v) x y = None) then (0, []) else if FSM.h_obs M1 (after_initial M1 u) x y = FSM.h_obs M1 (after_initial M1 v) x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (length (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G u) u) then 0 else length (shortest_list_or_default (cg_lookup G u) u)) + (if has_leaf T G cg_lookup (shortest_list_or_default (cg_lookup G v) v) then 0 else length (shortest_list_or_default (cg_lookup G v) v)), []) (List.product (inputs_as_list M1) (outputs_as_list M1)))
[PROOF STEP]
by force
[PROOF STATE]
proof (state)
this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (if \<not> isin T u' \<or> \<not> isin T v' then (errorValue, []) else foldl tryIO (minEst0, []) XY)

goal (1 subgoal):
 1. \<And>k u v. \<lbrakk>\<And>u v. \<lbrakk>u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))); u \<in> L M1; u \<in> L M2; v \<in> L M1; v \<in> L M2; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
proof (cases "\<not> isin T u' \<or> \<not> isin T v'")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<not> isin T u' \<or> \<not> isin T v' \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
 2. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
\<not> isin T u' \<or> \<not> isin T v'

goal (2 subgoals):
 1. \<not> isin T u' \<or> \<not> isin T v' \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
 2. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> isin T u' \<or> \<not> isin T v'
[PROOF STEP]
have *:"(get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = (errorValue,[])"
[PROOF STATE]
proof (prove)
using this:
\<not> isin T u' \<or> \<not> isin T v'

goal (1 subgoal):
 1. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (errorValue, [])
[PROOF STEP]
using res'
[PROOF STATE]
proof (prove)
using this:
\<not> isin T u' \<or> \<not> isin T v'
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (if \<not> isin T u' \<or> \<not> isin T v' then (errorValue, []) else foldl tryIO (minEst0, []) XY)

goal (1 subgoal):
 1. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (errorValue, [])
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (errorValue, [])

goal (2 subgoals):
 1. \<not> isin T u' \<or> \<not> isin T v' \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
 2. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
unfolding * fst_conv snd_conv errorValue
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (Suc minEst0 = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (Suc minEst0 \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([] @ \<gamma>)))
[PROOF STEP]
by (metis Suc.prems(1,3,5) Zero_not_Suc after_is_state append_Nil assms(1) assms(9))
[PROOF STATE]
proof (state)
this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> (\<not> isin T u' \<or> \<not> isin T v')

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> (\<not> isin T u' \<or> \<not> isin T v')
[PROOF STEP]
have res: "(get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = foldl tryIO (minEst0,[]) XY"
[PROOF STATE]
proof (prove)
using this:
\<not> (\<not> isin T u' \<or> \<not> isin T v')

goal (1 subgoal):
 1. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = foldl tryIO (minEst0, []) XY
[PROOF STEP]
using res'
[PROOF STATE]
proof (prove)
using this:
\<not> (\<not> isin T u' \<or> \<not> isin T v')
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = (if \<not> isin T u' \<or> \<not> isin T v' then (errorValue, []) else foldl tryIO (minEst0, []) XY)

goal (1 subgoal):
 1. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = foldl tryIO (minEst0, []) XY
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k) = foldl tryIO (minEst0, []) XY

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "converge M1 u u'" and "converge M2 u u'"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. converge M1 u u' &&& converge M2 u u'
[PROOF STEP]
unfolding u'
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. converge M1 u (shortest_list_or_default (cg_lookup G u) u) &&& converge M2 u (shortest_list_or_default (cg_lookup G u) u)
[PROOF STEP]
using shortest_list_or_default_elem[of "cg_lookup G u" u] assms(10) Suc.prems(1,2,3)
[PROOF STATE]
proof (prove)
using this:
shortest_list_or_default (cg_lookup G u) u \<in> Set.insert u (list.set (cg_lookup G u))
convergence_graph_lookup_invar M1 M2 cg_lookup G
u \<in> L M1
u \<in> L M2
v \<in> L M1

goal (1 subgoal):
 1. converge M1 u (shortest_list_or_default (cg_lookup G u) u) &&& converge M2 u (shortest_list_or_default (cg_lookup G u) u)
[PROOF STEP]
by (metis converge.elims(3) convergence_graph_lookup_invar_def insertE)+
[PROOF STATE]
proof (state)
this:
converge M1 u u'
converge M2 u u'

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "converge M1 v v'" and "converge M2 v v'"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. converge M1 v v' &&& converge M2 v v'
[PROOF STEP]
unfolding v'
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. converge M1 v (shortest_list_or_default (cg_lookup G v) v) &&& converge M2 v (shortest_list_or_default (cg_lookup G v) v)
[PROOF STEP]
using shortest_list_or_default_elem[of "cg_lookup G v" v] assms(10) Suc.prems
[PROOF STATE]
proof (prove)
using this:
shortest_list_or_default (cg_lookup G v) v \<in> Set.insert v (list.set (cg_lookup G v))
convergence_graph_lookup_invar M1 M2 cg_lookup G
u \<in> L M1
u \<in> L M2
v \<in> L M1
v \<in> L M2
after_initial M1 u \<noteq> after_initial M1 v

goal (1 subgoal):
 1. converge M1 v (shortest_list_or_default (cg_lookup G v) v) &&& converge M2 v (shortest_list_or_default (cg_lookup G v) v)
[PROOF STEP]
by (metis converge.elims(3) convergence_graph_lookup_invar_def insertE)+
[PROOF STATE]
proof (state)
this:
converge M1 v v'
converge M2 v v'

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "su \<in> states M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. su \<in> FSM.states M1
[PROOF STEP]
unfolding su
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 u \<in> FSM.states M1
[PROOF STEP]
using after_is_state[OF assms(1) Suc.prems(1)]
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u \<in> FSM.states M1

goal (1 subgoal):
 1. after_initial M1 u \<in> FSM.states M1
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
su \<in> FSM.states M1

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "sv \<in> states M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. sv \<in> FSM.states M1
[PROOF STEP]
unfolding sv
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 v \<in> FSM.states M1
[PROOF STEP]
using after_is_state[OF assms(1) Suc.prems(3)]
[PROOF STATE]
proof (prove)
using this:
after_initial M1 v \<in> FSM.states M1

goal (1 subgoal):
 1. after_initial M1 v \<in> FSM.states M1
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
sv \<in> FSM.states M1

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
define P where P: "P = (\<lambda> (ew :: (nat \<times> ('b \<times> 'c) list)) .
                                      (fst ew = 0 \<longrightarrow> \<not> converge M2 u v)
                                      \<and> (fst ew \<noteq> 0 \<longrightarrow>  (\<exists> \<gamma> . distinguishes M1 (after_initial M1 u) (after_initial M1 v) ((snd ew)@\<gamma>))))"
[PROOF STATE]
proof (state)
this:
P = (\<lambda>ew. (fst ew = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst ew \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd ew @ \<gamma>))))

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "P (minEst0,[])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (minEst0, [])
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. P (minEst0, [])
[PROOF STEP]
have "distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
[PROOF STEP]
using assms(9)[of su sv]
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>su \<in> FSM.states M1; sv \<in> FSM.states M1; su \<noteq> sv\<rbrakk> \<Longrightarrow> distinguishes M1 su sv (get_distinguishing_trace su sv)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
[PROOF STEP]
using \<open>su \<in> states M1\<close> \<open>sv \<in> states M1\<close>
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>su \<in> FSM.states M1; sv \<in> FSM.states M1; su \<noteq> sv\<rbrakk> \<Longrightarrow> distinguishes M1 su sv (get_distinguishing_trace su sv)
su \<in> FSM.states M1
sv \<in> FSM.states M1

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
[PROOF STEP]
using Suc.prems(5)
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>su \<in> FSM.states M1; sv \<in> FSM.states M1; su \<noteq> sv\<rbrakk> \<Longrightarrow> distinguishes M1 su sv (get_distinguishing_trace su sv)
su \<in> FSM.states M1
sv \<in> FSM.states M1
after_initial M1 u \<noteq> after_initial M1 v

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
[PROOF STEP]
unfolding bestPrefix0 su sv
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>after_initial M1 u \<in> FSM.states M1; after_initial M1 v \<in> FSM.states M1; after_initial M1 u \<noteq> after_initial M1 v\<rbrakk> \<Longrightarrow> distinguishes M1 (after_initial M1 u) (after_initial M1 v) (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v))
after_initial M1 u \<in> FSM.states M1
after_initial M1 v \<in> FSM.states M1
after_initial M1 u \<noteq> after_initial M1 v

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (get_distinguishing_trace (after_initial M1 u) (after_initial M1 v))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0

goal (1 subgoal):
 1. P (minEst0, [])
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0

goal (1 subgoal):
 1. P (minEst0, [])
[PROOF STEP]
have "minEst0 \<noteq> 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. minEst0 \<noteq> 0
[PROOF STEP]
unfolding minEst0
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. length bestPrefix0 + (if has_leaf T G cg_lookup u' then 0 else length u') + (if has_leaf T G cg_lookup v' then 0 else length v') \<noteq> 0
[PROOF STEP]
using calculation distinguishes_not_Nil[OF _ after_is_state[OF assms(1) Suc.prems(1)] after_is_state[OF assms(1) Suc.prems(3)]]
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
distinguishes M1 (after_initial M1 u) (after_initial M1 v) ?io \<Longrightarrow> ?io \<noteq> []

goal (1 subgoal):
 1. length bestPrefix0 + (if has_leaf T G cg_lookup u' then 0 else length u') + (if has_leaf T G cg_lookup v' then 0 else length v') \<noteq> 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
minEst0 \<noteq> 0

goal (1 subgoal):
 1. P (minEst0, [])
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
minEst0 \<noteq> 0
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
minEst0 \<noteq> 0

goal (1 subgoal):
 1. P (minEst0, [])
[PROOF STEP]
unfolding P fst_conv snd_conv
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) bestPrefix0
minEst0 \<noteq> 0

goal (1 subgoal):
 1. (minEst0 = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (minEst0 \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([] @ \<gamma>)))
[PROOF STEP]
by (metis append.left_neutral)
[PROOF STATE]
proof (state)
this:
P (minEst0, [])

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (minEst0, [])

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "errorValue > 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 < errorValue
[PROOF STEP]
unfolding errorValue
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 < Suc minEst0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
0 < errorValue

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "\<And> x y e w . e < errorValue \<Longrightarrow> P (e,w) \<Longrightarrow> P (tryIO (e,w) (x,y)) \<and> fst (tryIO (e,w) (x,y)) \<le> e"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>x y e w. \<lbrakk>e < errorValue; P (e, w)\<rbrakk> \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x y e w. \<lbrakk>e < errorValue; P (e, w)\<rbrakk> \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
fix x y e w
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x y e w. \<lbrakk>e < errorValue; P (e, w)\<rbrakk> \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
assume "e < errorValue" and "P (e,w)"
[PROOF STATE]
proof (state)
this:
e < errorValue
P (e, w)

goal (1 subgoal):
 1. \<And>x y e w. \<lbrakk>e < errorValue; P (e, w)\<rbrakk> \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have *:"\<And> x y a b f . (case (x, y) of (x, y) \<Rightarrow> (\<lambda>(a, b). f x y a b)) (a,b)  = f x y a b"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>x y a b f. (case (x, y) of (x, y) \<Rightarrow> \<lambda>(a, b). f x y a b) (a, b) = f x y a b
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(case (?x, ?y) of (x, y) \<Rightarrow> \<lambda>(a, b). ?f x y a b) (?a, ?b) = ?f ?x ?y ?a ?b

goal (1 subgoal):
 1. \<And>x y e w. \<lbrakk>e < errorValue; P (e, w)\<rbrakk> \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show "P (tryIO (e,w) (x,y)) \<and> fst (tryIO (e,w) (x,y)) \<le> e"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "e = 0")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. e = 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. e \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
e = 0

goal (2 subgoals):
 1. e = 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. e \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
e = 0
[PROOF STEP]
have "tryIO (e,w) (x,y) = (e,w)"
[PROOF STATE]
proof (prove)
using this:
e = 0

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
unfolding P tryIO fst_conv snd_conv case_prod_conv
[PROOF STATE]
proof (prove)
using this:
e = 0

goal (1 subgoal):
 1. (if e = 0 then (e, w) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (e, w) | Some v'' \<Rightarrow> let ea = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if ea \<noteq> 1 then if has_leaf T G cg_lookup v'' then ea + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then ea + length v' + 1 else ea else ea; e'' = e' + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) in if e'' \<le> e then (e'', [(x, y)]) else (e, w) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> let ea = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if ea \<noteq> 1 then if has_leaf T G cg_lookup u'' then ea + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then ea + length u' + 1 else ea else ea; e'' = e' + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) in if e'' \<le> e then (e'', [(x, y)]) else (e, w) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (e, w) else let (ea, wa) = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k in if ea = 0 then (0, []) else if ea \<le> e then (ea, (x, y) # wa) else (e, w)) = (e, w)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (e, w)

goal (2 subgoals):
 1. e = 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. e \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>P (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)
P (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. e \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. e \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
e \<noteq> 0

goal (1 subgoal):
 1. e \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "get_extension T G cg_lookup u' x y")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. get_extension T G cg_lookup u' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup u' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case None
[PROOF STATE]
proof (state)
this:
get_extension T G cg_lookup u' x y = None

goal (2 subgoals):
 1. get_extension T G cg_lookup u' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup u' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "get_extension T G cg_lookup v' x y")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case None
[PROOF STATE]
proof (state)
this:
get_extension T G cg_lookup v' x y = None

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
get_extension T G cg_lookup v' x y = None
[PROOF STEP]
have "tryIO (e,w) (x,y) = (e,w)"
[PROOF STATE]
proof (prove)
using this:
get_extension T G cg_lookup v' x y = None

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
using \<open>get_extension T G cg_lookup u' x y = None\<close>
[PROOF STATE]
proof (prove)
using this:
get_extension T G cg_lookup v' x y = None
get_extension T G cg_lookup u' x y = None

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
unfolding tryIO
[PROOF STATE]
proof (prove)
using this:
get_extension T G cg_lookup v' x y = None
get_extension T G cg_lookup u' x y = None

goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if e \<noteq> 1 then if has_leaf T G cg_lookup v'' then e + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then e + length v' + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if e \<noteq> 1 then if has_leaf T G cg_lookup u'' then e + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then e + length u' + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else let (e, w) = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k in if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (e, w)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (e, w)

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>P (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)
P (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case (Some v'')
[PROOF STATE]
proof (state)
this:
get_extension T G cg_lookup v' x y = Some v''

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
define c where c: "c = estimate_growth M1 get_distinguishing_trace su sv x y errorValue"
[PROOF STATE]
proof (state)
this:
c = estimate_growth M1 get_distinguishing_trace su sv x y errorValue

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
define c' where c': "c' = (if c \<noteq> 1 then if has_leaf T G cg_lookup v'' then c + 1 else if \<not>(has_leaf T G cg_lookup (v''@[(x,y)])) then c + length v' + 1 else c else c)"
[PROOF STATE]
proof (state)
this:
c' = (if c \<noteq> 1 then if has_leaf T G cg_lookup v'' then c + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then c + length v' + 1 else c else c)

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
define c'' where c'': "c'' = c' + (if \<not>(has_leaf T G cg_lookup u') then length u' else 0)"
[PROOF STATE]
proof (state)
this:
c'' = c' + (if \<not> has_leaf T G cg_lookup u' then length u' else 0)

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "tryIO (e,w) (x,y) = (if c'' \<le> e then (c'',[(x,y)]) else (e,w))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))
[PROOF STEP]
unfolding c c' c'' tryIO Let_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> e then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (e, w))
[PROOF STEP]
using None Some False
[PROOF STATE]
proof (prove)
using this:
get_extension T G cg_lookup u' x y = None
get_extension T G cg_lookup v' x y = Some v''
e \<noteq> 0

goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> e then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (e, w))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "c'' \<le> e")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
c'' \<le> e

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c'' \<le> e
[PROOF STEP]
have "c'' < errorValue"
[PROOF STATE]
proof (prove)
using this:
c'' \<le> e

goal (1 subgoal):
 1. c'' < errorValue
[PROOF STEP]
using \<open>e < errorValue\<close>
[PROOF STATE]
proof (prove)
using this:
c'' \<le> e
e < errorValue

goal (1 subgoal):
 1. c'' < errorValue
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
c'' < errorValue

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c'' < errorValue
[PROOF STEP]
have "c' < errorValue"
[PROOF STATE]
proof (prove)
using this:
c'' < errorValue

goal (1 subgoal):
 1. c' < errorValue
[PROOF STEP]
unfolding c''
[PROOF STATE]
proof (prove)
using this:
c' + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) < errorValue

goal (1 subgoal):
 1. c' < errorValue
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
c' < errorValue

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c' < errorValue
[PROOF STEP]
have "estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue"
[PROOF STATE]
proof (prove)
using this:
c' < errorValue

goal (1 subgoal):
 1. estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue
[PROOF STEP]
unfolding c' c
[PROOF STATE]
proof (prove)
using this:
(if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) < errorValue

goal (1 subgoal):
 1. estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue
[PROOF STEP]
using add_lessD1
[PROOF STATE]
proof (prove)
using this:
(if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) < errorValue
?i + ?j < ?k \<Longrightarrow> ?i < ?k

goal (1 subgoal):
 1. estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "c > 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 < c
[PROOF STEP]
using estimate_growth_Suc[OF \<open>errorValue > 0\<close>]
[PROOF STATE]
proof (prove)
using this:
0 < estimate_growth ?M ?get_distinguishing_trace ?q1.0 ?q2.0 ?x ?y errorValue

goal (1 subgoal):
 1. 0 < c
[PROOF STEP]
unfolding c
[PROOF STATE]
proof (prove)
using this:
0 < estimate_growth ?M ?get_distinguishing_trace ?q1.0 ?q2.0 ?x ?y errorValue

goal (1 subgoal):
 1. 0 < estimate_growth M1 get_distinguishing_trace su sv x y errorValue
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
0 < c

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
0 < c
[PROOF STEP]
have "c'' > 0"
[PROOF STATE]
proof (prove)
using this:
0 < c

goal (1 subgoal):
 1. 0 < c''
[PROOF STEP]
unfolding c' c''
[PROOF STATE]
proof (prove)
using this:
0 < c

goal (1 subgoal):
 1. 0 < (if c \<noteq> 1 then if has_leaf T G cg_lookup v'' then c + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then c + length v' + 1 else c else c) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0)
[PROOF STEP]
using add_gr_0
[PROOF STATE]
proof (prove)
using this:
0 < c
(0 < ?m + ?n) = (0 < ?m \<or> 0 < ?n)

goal (1 subgoal):
 1. 0 < (if c \<noteq> 1 then if has_leaf T G cg_lookup v'' then c + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then c + length v' + 1 else c else c) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0)
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
0 < c''

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
0 < c''
[PROOF STEP]
have "c'' \<noteq> 0"
[PROOF STATE]
proof (prove)
using this:
0 < c''

goal (1 subgoal):
 1. c'' \<noteq> 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
c'' \<noteq> 0

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c'' \<noteq> 0
[PROOF STEP]
have "P (c'',[(x,y)])"
[PROOF STATE]
proof (prove)
using this:
c'' \<noteq> 0

goal (1 subgoal):
 1. P (c'', [(x, y)])
[PROOF STEP]
using True estimate_growth_result[OF assms(1,3) \<open>su \<in> states M1\<close> \<open>sv \<in> states M1\<close> \<open>estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue\<close>]
[PROOF STATE]
proof (prove)
using this:
c'' \<noteq> 0
c'' \<le> e
\<exists>\<gamma>. distinguishes M1 su sv ([(x, y)] @ \<gamma>)

goal (1 subgoal):
 1. P (c'', [(x, y)])
[PROOF STEP]
unfolding P fst_conv su sv snd_conv
[PROOF STATE]
proof (prove)
using this:
c'' \<noteq> 0
c'' \<le> e
\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([(x, y)] @ \<gamma>)

goal (1 subgoal):
 1. (c'' = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (c'' \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([(x, y)] @ \<gamma>)))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
P (c'', [(x, y)])

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
P (c'', [(x, y)])
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
P (c'', [(x, y)])

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>tryIO (e,w) (x,y) = (if c'' \<le> e then (c'',[(x,y)]) else (e,w))\<close> True
[PROOF STATE]
proof (prove)
using this:
P (c'', [(x, y)])
tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))
c'' \<le> e

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> c'' \<le> e

goal (1 subgoal):
 1. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> c'' \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<not> c'' \<le> e

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>tryIO (e,w) (x,y) = (if c'' \<le> e then (c'',[(x,y)]) else (e,w))\<close> \<open>P (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> c'' \<le> e
tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))
P (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup u' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup u' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case (Some u'')
[PROOF STATE]
proof (state)
this:
get_extension T G cg_lookup u' x y = Some u''

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup u' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "get_extension T G cg_lookup v' x y")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case None
[PROOF STATE]
proof (state)
this:
get_extension T G cg_lookup v' x y = None

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
define c where c: "c = estimate_growth M1 get_distinguishing_trace su sv x y errorValue"
[PROOF STATE]
proof (state)
this:
c = estimate_growth M1 get_distinguishing_trace su sv x y errorValue

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
define c' where c': "c' = (if c \<noteq> 1 then if has_leaf T G cg_lookup u'' then c + 1 else if \<not>(has_leaf T G cg_lookup (u''@[(x,y)])) then c + length u' + 1 else c else c)"
[PROOF STATE]
proof (state)
this:
c' = (if c \<noteq> 1 then if has_leaf T G cg_lookup u'' then c + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then c + length u' + 1 else c else c)

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
define c'' where c'': "c'' = c' + (if \<not>(has_leaf T G cg_lookup v') then length v' else 0)"
[PROOF STATE]
proof (state)
this:
c'' = c' + (if \<not> has_leaf T G cg_lookup v' then length v' else 0)

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "tryIO (e,w) (x,y) = (if c'' \<le> e then (c'',[(x,y)]) else (e,w))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))
[PROOF STEP]
unfolding c c' c'' tryIO Let_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> e then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (e, w))
[PROOF STEP]
using None Some False
[PROOF STATE]
proof (prove)
using this:
get_extension T G cg_lookup v' x y = None
get_extension T G cg_lookup u' x y = Some u''
e \<noteq> 0

goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> e then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (e, w))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))

goal (2 subgoals):
 1. get_extension T G cg_lookup v' x y = None \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "c'' \<le> e")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
c'' \<le> e

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c'' \<le> e
[PROOF STEP]
have "c'' < errorValue"
[PROOF STATE]
proof (prove)
using this:
c'' \<le> e

goal (1 subgoal):
 1. c'' < errorValue
[PROOF STEP]
using \<open>e < errorValue\<close>
[PROOF STATE]
proof (prove)
using this:
c'' \<le> e
e < errorValue

goal (1 subgoal):
 1. c'' < errorValue
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
c'' < errorValue

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c'' < errorValue
[PROOF STEP]
have "c' < errorValue"
[PROOF STATE]
proof (prove)
using this:
c'' < errorValue

goal (1 subgoal):
 1. c' < errorValue
[PROOF STEP]
unfolding c''
[PROOF STATE]
proof (prove)
using this:
c' + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) < errorValue

goal (1 subgoal):
 1. c' < errorValue
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
c' < errorValue

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c' < errorValue
[PROOF STEP]
have "estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue"
[PROOF STATE]
proof (prove)
using this:
c' < errorValue

goal (1 subgoal):
 1. estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue
[PROOF STEP]
unfolding c' c
[PROOF STATE]
proof (prove)
using this:
(if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) < errorValue

goal (1 subgoal):
 1. estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue
[PROOF STEP]
using add_lessD1
[PROOF STATE]
proof (prove)
using this:
(if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) < errorValue
?i + ?j < ?k \<Longrightarrow> ?i < ?k

goal (1 subgoal):
 1. estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "c > 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 < c
[PROOF STEP]
using estimate_growth_Suc[OF \<open>errorValue > 0\<close>]
[PROOF STATE]
proof (prove)
using this:
0 < estimate_growth ?M ?get_distinguishing_trace ?q1.0 ?q2.0 ?x ?y errorValue

goal (1 subgoal):
 1. 0 < c
[PROOF STEP]
unfolding c
[PROOF STATE]
proof (prove)
using this:
0 < estimate_growth ?M ?get_distinguishing_trace ?q1.0 ?q2.0 ?x ?y errorValue

goal (1 subgoal):
 1. 0 < estimate_growth M1 get_distinguishing_trace su sv x y errorValue
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
0 < c

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
0 < c
[PROOF STEP]
have "c'' > 0"
[PROOF STATE]
proof (prove)
using this:
0 < c

goal (1 subgoal):
 1. 0 < c''
[PROOF STEP]
unfolding c' c''
[PROOF STATE]
proof (prove)
using this:
0 < c

goal (1 subgoal):
 1. 0 < (if c \<noteq> 1 then if has_leaf T G cg_lookup u'' then c + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then c + length u' + 1 else c else c) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0)
[PROOF STEP]
using add_gr_0
[PROOF STATE]
proof (prove)
using this:
0 < c
(0 < ?m + ?n) = (0 < ?m \<or> 0 < ?n)

goal (1 subgoal):
 1. 0 < (if c \<noteq> 1 then if has_leaf T G cg_lookup u'' then c + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then c + length u' + 1 else c else c) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0)
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
0 < c''

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
0 < c''
[PROOF STEP]
have "c'' \<noteq> 0"
[PROOF STATE]
proof (prove)
using this:
0 < c''

goal (1 subgoal):
 1. c'' \<noteq> 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
c'' \<noteq> 0

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
c'' \<noteq> 0
[PROOF STEP]
have "P (c'',[(x,y)])"
[PROOF STATE]
proof (prove)
using this:
c'' \<noteq> 0

goal (1 subgoal):
 1. P (c'', [(x, y)])
[PROOF STEP]
using True estimate_growth_result[OF assms(1,3) \<open>su \<in> states M1\<close> \<open>sv \<in> states M1\<close> \<open>estimate_growth M1 get_distinguishing_trace su sv x y errorValue < errorValue\<close>]
[PROOF STATE]
proof (prove)
using this:
c'' \<noteq> 0
c'' \<le> e
\<exists>\<gamma>. distinguishes M1 su sv ([(x, y)] @ \<gamma>)

goal (1 subgoal):
 1. P (c'', [(x, y)])
[PROOF STEP]
unfolding P fst_conv su sv snd_conv
[PROOF STATE]
proof (prove)
using this:
c'' \<noteq> 0
c'' \<le> e
\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([(x, y)] @ \<gamma>)

goal (1 subgoal):
 1. (c'' = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (c'' \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([(x, y)] @ \<gamma>)))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
P (c'', [(x, y)])

goal (2 subgoals):
 1. c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
P (c'', [(x, y)])
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
P (c'', [(x, y)])

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>tryIO (e,w) (x,y) = (if c'' \<le> e then (c'',[(x,y)]) else (e,w))\<close> True
[PROOF STATE]
proof (prove)
using this:
P (c'', [(x, y)])
tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))
c'' \<le> e

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> c'' \<le> e

goal (1 subgoal):
 1. \<not> c'' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> c'' \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<not> c'' \<le> e

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>tryIO (e,w) (x,y) = (if c'' \<le> e then (c'',[(x,y)]) else (e,w))\<close> \<open>P (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> c'' \<le> e
tryIO (e, w) (x, y) = (if c'' \<le> e then (c'', [(x, y)]) else (e, w))
P (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case (Some v'')
[PROOF STATE]
proof (state)
this:
get_extension T G cg_lookup v' x y = Some v''

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "u' \<in> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u' \<in> L M1
[PROOF STEP]
using \<open>converge M1 u u'\<close> converge.simps
[PROOF STATE]
proof (prove)
using this:
converge M1 u u'
converge ?M ?\<pi> ?\<tau> = (?\<pi> \<in> L ?M \<and> ?\<tau> \<in> L ?M \<and> LS ?M (after_initial ?M ?\<pi>) = LS ?M (after_initial ?M ?\<tau>))

goal (1 subgoal):
 1. u' \<in> L M1
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
u' \<in> L M1

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "v' \<in> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v' \<in> L M1
[PROOF STEP]
using \<open>converge M1 v v'\<close> converge.simps
[PROOF STATE]
proof (prove)
using this:
converge M1 v v'
converge ?M ?\<pi> ?\<tau> = (?\<pi> \<in> L ?M \<and> ?\<tau> \<in> L ?M \<and> LS ?M (after_initial ?M ?\<pi>) = LS ?M (after_initial ?M ?\<tau>))

goal (1 subgoal):
 1. v' \<in> L M1
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
v' \<in> L M1

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "u' \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u' \<in> L M2
[PROOF STEP]
using \<open>converge M2 u u'\<close> converge.simps
[PROOF STATE]
proof (prove)
using this:
converge M2 u u'
converge ?M ?\<pi> ?\<tau> = (?\<pi> \<in> L ?M \<and> ?\<tau> \<in> L ?M \<and> LS ?M (after_initial ?M ?\<pi>) = LS ?M (after_initial ?M ?\<tau>))

goal (1 subgoal):
 1. u' \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
u' \<in> L M2

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "v' \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v' \<in> L M2
[PROOF STEP]
using \<open>converge M2 v v'\<close> converge.simps
[PROOF STATE]
proof (prove)
using this:
converge M2 v v'
converge ?M ?\<pi> ?\<tau> = (?\<pi> \<in> L ?M \<and> ?\<tau> \<in> L ?M \<and> LS ?M (after_initial ?M ?\<pi>) = LS ?M (after_initial ?M ?\<tau>))

goal (1 subgoal):
 1. v' \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
v' \<in> L M2

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "converge M1 u' u''" and "u'' @ [(x, y)] \<in> set T"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. converge M1 u' u'' &&& u'' @ [(x, y)] \<in> Prefix_Tree.set T
[PROOF STEP]
using get_extension_result(1,3)[OF \<open>u' \<in> L M1\<close> \<open>u' \<in> L M2\<close> assms(10) \<open>get_extension T G cg_lookup u' x y = Some u''\<close>]
[PROOF STATE]
proof (prove)
using this:
converge M1 u' u''
u'' @ [(x, y)] \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. converge M1 u' u'' &&& u'' @ [(x, y)] \<in> Prefix_Tree.set T
[PROOF STEP]
by blast+
[PROOF STATE]
proof (state)
this:
converge M1 u' u''
u'' @ [(x, y)] \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
converge M1 u' u''
u'' @ [(x, y)] \<in> Prefix_Tree.set T
[PROOF STEP]
have "converge M1 u u''"
[PROOF STATE]
proof (prove)
using this:
converge M1 u' u''
u'' @ [(x, y)] \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. converge M1 u u''
[PROOF STEP]
using \<open>converge M1 u u'\<close>
[PROOF STATE]
proof (prove)
using this:
converge M1 u' u''
u'' @ [(x, y)] \<in> Prefix_Tree.set T
converge M1 u u'

goal (1 subgoal):
 1. converge M1 u u''
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
converge M1 u u''

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
converge M1 u u''
[PROOF STEP]
have "u'' \<in> set T \<inter> L M1"
[PROOF STATE]
proof (prove)
using this:
converge M1 u u''

goal (1 subgoal):
 1. u'' \<in> Prefix_Tree.set T \<inter> L M1
[PROOF STEP]
using set_prefix[OF \<open>u'' @ [(x, y)] \<in> set T\<close>]
[PROOF STATE]
proof (prove)
using this:
converge M1 u u''
u'' \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. u'' \<in> Prefix_Tree.set T \<inter> L M1
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
u'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "converge M1 v' v''" and "v'' @ [(x, y)] \<in> set T"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. converge M1 v' v'' &&& v'' @ [(x, y)] \<in> Prefix_Tree.set T
[PROOF STEP]
using get_extension_result[OF \<open>v' \<in> L M1\<close> \<open>v' \<in> L M2\<close> assms(10) \<open>get_extension T G cg_lookup v' x y = Some v''\<close>]
[PROOF STATE]
proof (prove)
using this:
converge M1 v' v''
v'' \<in> L M2 \<Longrightarrow> converge M2 v' v''
v'' @ [(x, y)] \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. converge M1 v' v'' &&& v'' @ [(x, y)] \<in> Prefix_Tree.set T
[PROOF STEP]
by blast+
[PROOF STATE]
proof (state)
this:
converge M1 v' v''
v'' @ [(x, y)] \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
converge M1 v' v''
v'' @ [(x, y)] \<in> Prefix_Tree.set T
[PROOF STEP]
have "converge M1 v v''"
[PROOF STATE]
proof (prove)
using this:
converge M1 v' v''
v'' @ [(x, y)] \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. converge M1 v v''
[PROOF STEP]
using \<open>converge M1 v v'\<close>
[PROOF STATE]
proof (prove)
using this:
converge M1 v' v''
v'' @ [(x, y)] \<in> Prefix_Tree.set T
converge M1 v v'

goal (1 subgoal):
 1. converge M1 v v''
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
converge M1 v v''

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
converge M1 v v''
[PROOF STEP]
have "v'' \<in> set T \<inter> L M1"
[PROOF STATE]
proof (prove)
using this:
converge M1 v v''

goal (1 subgoal):
 1. v'' \<in> Prefix_Tree.set T \<inter> L M1
[PROOF STEP]
using set_prefix[OF \<open>v'' @ [(x, y)] \<in> set T\<close>]
[PROOF STATE]
proof (prove)
using this:
converge M1 v v''
v'' \<in> Prefix_Tree.set T

goal (1 subgoal):
 1. v'' \<in> Prefix_Tree.set T \<inter> L M1
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
v'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. \<And>a. get_extension T G cg_lookup v' x y = Some a \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "(h_obs M1 su x y = None) \<noteq> (h_obs M1 sv x y = None)")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
(FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)

goal (2 subgoals):
 1. (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
(FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)
[PROOF STEP]
have "tryIO (e,w) (x,y) = (0,[])"
[PROOF STATE]
proof (prove)
using this:
(FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (0, [])
[PROOF STEP]
using Some \<open>get_extension T G cg_lookup u' x y = Some u''\<close> False
[PROOF STATE]
proof (prove)
using this:
(FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)
get_extension T G cg_lookup v' x y = Some v''
get_extension T G cg_lookup u' x y = Some u''
e \<noteq> 0

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (0, [])
[PROOF STEP]
unfolding tryIO Let_def
[PROOF STATE]
proof (prove)
using this:
(FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)
get_extension T G cg_lookup v' x y = Some v''
get_extension T G cg_lookup u' x y = Some u''
e \<noteq> 0

goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (0, [])
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (0, [])

goal (2 subgoals):
 1. (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "\<not> converge M2 u v"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
note \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close>
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
[PROOF STEP]
have "u' \<in> L M2" and "v' \<in> L M2"
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. u' \<in> L M2 &&& v' \<in> L M2
[PROOF STEP]
using False \<open>u' \<in> L M1\<close> \<open>v' \<in> L M1\<close> \<open>\<not> (\<not> isin T u' \<or> \<not> isin T v')\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
e \<noteq> 0
u' \<in> L M1
v' \<in> L M1
\<not> (\<not> isin T u' \<or> \<not> isin T v')

goal (1 subgoal):
 1. u' \<in> L M2 &&& v' \<in> L M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
u' \<in> L M2
v' \<in> L M2

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
have "u'' \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u'' \<in> L M2
[PROOF STEP]
using \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close> \<open>u'' \<in> set T \<inter> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
u'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. u'' \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
u'' \<in> L M2

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
u'' \<in> L M2
[PROOF STEP]
have "converge M2 u' u''"
[PROOF STATE]
proof (prove)
using this:
u'' \<in> L M2

goal (1 subgoal):
 1. converge M2 u' u''
[PROOF STEP]
using get_extension_result(2)[OF \<open>u' \<in> L M1\<close> \<open>u' \<in> L M2\<close> assms(10) \<open>get_extension T G cg_lookup u' x y = Some u''\<close>]
[PROOF STATE]
proof (prove)
using this:
u'' \<in> L M2
u'' \<in> L M2 \<Longrightarrow> converge M2 u' u''

goal (1 subgoal):
 1. converge M2 u' u''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
converge M2 u' u''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
converge M2 u' u''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
note \<open>converge M2 u u'\<close>
[PROOF STATE]
proof (state)
this:
converge M2 u u'

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
converge M2 u' u''
converge M2 u u'
[PROOF STEP]
have "converge M2 u u''"
[PROOF STATE]
proof (prove)
using this:
converge M2 u' u''
converge M2 u u'

goal (1 subgoal):
 1. converge M2 u u''
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
converge M2 u u''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
have "v'' \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v'' \<in> L M2
[PROOF STEP]
using \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close> \<open>v'' \<in> set T \<inter> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
v'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. v'' \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
v'' \<in> L M2

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
v'' \<in> L M2
[PROOF STEP]
have "converge M2 v' v''"
[PROOF STATE]
proof (prove)
using this:
v'' \<in> L M2

goal (1 subgoal):
 1. converge M2 v' v''
[PROOF STEP]
using get_extension_result(2)[OF \<open>v' \<in> L M1\<close> \<open>v' \<in> L M2\<close> assms(10) \<open>get_extension T G cg_lookup v' x y = Some v''\<close>]
[PROOF STATE]
proof (prove)
using this:
v'' \<in> L M2
v'' \<in> L M2 \<Longrightarrow> converge M2 v' v''

goal (1 subgoal):
 1. converge M2 v' v''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
converge M2 v' v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
converge M2 v' v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
note \<open>converge M2 v v'\<close>
[PROOF STATE]
proof (state)
this:
converge M2 v v'

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
converge M2 v' v''
converge M2 v v'
[PROOF STEP]
have "converge M2 v v''"
[PROOF STATE]
proof (prove)
using this:
converge M2 v' v''
converge M2 v v'

goal (1 subgoal):
 1. converge M2 v v''
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
converge M2 v v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
have "distinguishes M1 su sv ([(x,y)])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. distinguishes M1 su sv [(x, y)]
[PROOF STEP]
using h_obs_distinguishes[OF assms(1), of su x y _ sv]
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>FSM.h_obs M1 su x y = Some ?q1'; FSM.h_obs M1 sv x y = None\<rbrakk> \<Longrightarrow> distinguishes M1 su sv [(x, y)]

goal (1 subgoal):
 1. distinguishes M1 su sv [(x, y)]
[PROOF STEP]
using distinguishes_sym[OF h_obs_distinguishes[OF assms(1), of sv x y _ su]]
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>FSM.h_obs M1 su x y = Some ?q1'; FSM.h_obs M1 sv x y = None\<rbrakk> \<Longrightarrow> distinguishes M1 su sv [(x, y)]
\<lbrakk>FSM.h_obs M1 sv x y = Some ?q1'1; FSM.h_obs M1 su x y = None\<rbrakk> \<Longrightarrow> distinguishes M1 su sv [(x, y)]

goal (1 subgoal):
 1. distinguishes M1 su sv [(x, y)]
[PROOF STEP]
using True
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>FSM.h_obs M1 su x y = Some ?q1'; FSM.h_obs M1 sv x y = None\<rbrakk> \<Longrightarrow> distinguishes M1 su sv [(x, y)]
\<lbrakk>FSM.h_obs M1 sv x y = Some ?q1'1; FSM.h_obs M1 su x y = None\<rbrakk> \<Longrightarrow> distinguishes M1 su sv [(x, y)]
(FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)

goal (1 subgoal):
 1. distinguishes M1 su sv [(x, y)]
[PROOF STEP]
by (cases "h_obs M1 su x y"; cases "h_obs M1 sv x y"; metis)
[PROOF STATE]
proof (state)
this:
distinguishes M1 su sv [(x, y)]

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
distinguishes M1 su sv [(x, y)]
[PROOF STEP]
have "distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([(x,y)])"
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 su sv [(x, y)]

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) [(x, y)]
[PROOF STEP]
unfolding su sv
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) [(x, y)]

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) [(x, y)]
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) [(x, y)]

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
show "\<not> converge M2 u v"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
using distinguish_converge_diverge[OF assms(1-3) _ _ \<open>converge M1 u u''\<close> \<open>converge M1 v v''\<close> \<open>converge M2 u u''\<close> \<open>converge M2 v v''\<close> \<open>distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([(x,y)])\<close> \<open>u'' @ [(x, y)] \<in> set T\<close> \<open>v'' @ [(x, y)] \<in> set T\<close> \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close>]
                          \<open>u'' \<in> set T \<inter> L M1\<close> \<open>v'' \<in> set T \<inter> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>u'' \<in> L M1; v'' \<in> L M1\<rbrakk> \<Longrightarrow> \<not> converge M2 u v
u'' \<in> Prefix_Tree.set T \<inter> L M1
v'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<not> converge M2 u v

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<not> converge M2 u v

goal (2 subgoals):
 1. (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> converge M2 u v
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u v

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
unfolding P \<open>tryIO (e,w) (x,y) = (0,[])\<close> fst_conv snd_conv su sv
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u v

goal (1 subgoal):
 1. ((0 = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (0 \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) ([] @ \<gamma>)))) \<and> 0 \<le> e
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)

goal (1 subgoal):
 1. \<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "h_obs M1 su x y = h_obs M1 sv x y")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y

goal (2 subgoals):
 1. FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y
[PROOF STEP]
have "tryIO (e,w) (x,y) = (e,w)"
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
using \<open>get_extension T G cg_lookup u' x y = Some u''\<close> Some
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y
get_extension T G cg_lookup u' x y = Some u''
get_extension T G cg_lookup v' x y = Some v''

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
unfolding tryIO
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y
get_extension T G cg_lookup u' x y = Some u''
get_extension T G cg_lookup v' x y = Some v''

goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if e \<noteq> 1 then if has_leaf T G cg_lookup v'' then e + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then e + length v' + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> let e = estimate_growth M1 get_distinguishing_trace su sv x y errorValue; e' = if e \<noteq> 1 then if has_leaf T G cg_lookup u'' then e + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then e + length u' + 1 else e else e; e'' = e' + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) in if e'' \<le> minEst then (e'', [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else let (e, w) = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k in if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (e, w)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (e, w)

goal (2 subgoals):
 1. FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>P (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)
P (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y
[PROOF STEP]
have "h_obs M1 su x y \<noteq> None" and "h_obs M1 sv x y \<noteq> None"
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> None &&& FSM.h_obs M1 sv x y \<noteq> None
[PROOF STEP]
using \<open>\<not> (h_obs M1 su x y = None) \<noteq> (h_obs M1 sv x y = None)\<close>
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y
\<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> None &&& FSM.h_obs M1 sv x y \<noteq> None
[PROOF STEP]
by metis+
[PROOF STATE]
proof (state)
this:
FSM.h_obs M1 su x y \<noteq> None
FSM.h_obs M1 sv x y \<noteq> None

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "u''@[(x,y)] \<in> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u'' @ [(x, y)] \<in> L M1
[PROOF STEP]
by (metis \<open>converge M1 u u''\<close> \<open>h_obs M1 su x y \<noteq> None\<close> after_language_iff assms(1) converge.elims(2) h_obs_language_single_transition_iff su)
[PROOF STATE]
proof (state)
this:
u'' @ [(x, y)] \<in> L M1

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "v''@[(x,y)] \<in> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v'' @ [(x, y)] \<in> L M1
[PROOF STEP]
by (metis \<open>converge M1 v v''\<close> \<open>h_obs M1 sv x y \<noteq> None\<close> after_language_iff assms(1) converge.elims(2) h_obs_language_single_transition_iff sv)
[PROOF STATE]
proof (state)
this:
v'' @ [(x, y)] \<in> L M1

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "u''@[(x,y)] \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u'' @ [(x, y)] \<in> L M2
[PROOF STEP]
using \<open>u''@[(x,y)] \<in> L M1\<close> \<open>u''@[(x,y)] \<in> set T\<close> \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close>
[PROOF STATE]
proof (prove)
using this:
u'' @ [(x, y)] \<in> L M1
u'' @ [(x, y)] \<in> Prefix_Tree.set T
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. u'' @ [(x, y)] \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
u'' @ [(x, y)] \<in> L M2

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "v''@[(x,y)] \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v'' @ [(x, y)] \<in> L M2
[PROOF STEP]
using \<open>v''@[(x,y)] \<in> L M1\<close> \<open>v''@[(x,y)] \<in> set T\<close> \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close>
[PROOF STATE]
proof (prove)
using this:
v'' @ [(x, y)] \<in> L M1
v'' @ [(x, y)] \<in> Prefix_Tree.set T
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. v'' @ [(x, y)] \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
v'' @ [(x, y)] \<in> L M2

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "FSM.after M1 (FSM.initial M1) (u'' @ [(x, y)]) \<noteq> FSM.after M1 (FSM.initial M1) (v'' @ [(x, y)])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
using False \<open>converge M1 u u''\<close> \<open>converge M1 v v''\<close>
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y
converge M1 u u''
converge M1 v v''

goal (1 subgoal):
 1. after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
unfolding su sv
[PROOF STATE]
proof (prove)
using this:
FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y
converge M1 u u''
converge M1 v v''

goal (1 subgoal):
 1. after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
(* auto-generated proof *)
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
assume a1: "h_obs M1 (FSM.after M1 (FSM.initial M1) u) x y \<noteq> h_obs M1 (FSM.after M1 (FSM.initial M1) v) x y"
[PROOF STATE]
proof (state)
this:
FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
have f2: "\<forall>f ps psa. converge (f::('a, 'b, 'c) fsm) ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (FSM.after f (FSM.initial f) ps) = LS f (FSM.after f (FSM.initial f) psa))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>f ps psa. converge f ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (after_initial f ps) = LS f (after_initial f psa))
[PROOF STEP]
by (meson converge.simps)
[PROOF STATE]
proof (state)
this:
\<forall>f ps psa. converge f ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (after_initial f ps) = LS f (after_initial f psa))

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>f ps psa. converge f ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (after_initial f ps) = LS f (after_initial f psa))
[PROOF STEP]
have f3: "u \<in> L M1 \<and> u'' \<in> L M1 \<and> LS M1 (FSM.after M1 (FSM.initial M1) u) = LS M1 (FSM.after M1 (FSM.initial M1) u'')"
[PROOF STATE]
proof (prove)
using this:
\<forall>f ps psa. converge f ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (after_initial f ps) = LS f (after_initial f psa))

goal (1 subgoal):
 1. u \<in> L M1 \<and> u'' \<in> L M1 \<and> LS M1 (after_initial M1 u) = LS M1 (after_initial M1 u'')
[PROOF STEP]
using \<open>converge M1 u u''\<close>
[PROOF STATE]
proof (prove)
using this:
\<forall>f ps psa. converge f ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (after_initial f ps) = LS f (after_initial f psa))
converge M1 u u''

goal (1 subgoal):
 1. u \<in> L M1 \<and> u'' \<in> L M1 \<and> LS M1 (after_initial M1 u) = LS M1 (after_initial M1 u'')
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
u \<in> L M1 \<and> u'' \<in> L M1 \<and> LS M1 (after_initial M1 u) = LS M1 (after_initial M1 u'')

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
have f4: "\<forall>f ps psa. \<not> minimal (f::('a, 'b, 'c) fsm) \<or> \<not> observable f \<or> ps \<notin> L f \<or> psa \<notin> L f \<or> converge f ps psa = (FSM.after f (FSM.initial f) ps = FSM.after f (FSM.initial f) psa)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>f ps psa. \<not> minimal f \<or> \<not> observable f \<or> ps \<notin> L f \<or> psa \<notin> L f \<or> converge f ps psa = (after_initial f ps = after_initial f psa)
[PROOF STEP]
using convergence_minimal
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>minimal ?M; observable ?M; ?\<alpha> \<in> L ?M; ?\<beta> \<in> L ?M\<rbrakk> \<Longrightarrow> converge ?M ?\<alpha> ?\<beta> = (after_initial ?M ?\<alpha> = after_initial ?M ?\<beta>)

goal (1 subgoal):
 1. \<forall>f ps psa. \<not> minimal f \<or> \<not> observable f \<or> ps \<notin> L f \<or> psa \<notin> L f \<or> converge f ps psa = (after_initial f ps = after_initial f psa)
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<forall>f ps psa. \<not> minimal f \<or> \<not> observable f \<or> ps \<notin> L f \<or> psa \<notin> L f \<or> converge f ps psa = (after_initial f ps = after_initial f psa)

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
have f5: "v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (FSM.after M1 (FSM.initial M1) v) = LS M1 (FSM.after M1 (FSM.initial M1) v'')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')
[PROOF STEP]
using f2 \<open>converge M1 v v''\<close>
[PROOF STATE]
proof (prove)
using this:
\<forall>f ps psa. converge f ps psa = (ps \<in> L f \<and> psa \<in> L f \<and> LS f (after_initial f ps) = LS f (after_initial f psa))
converge M1 v v''

goal (1 subgoal):
 1. v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')
[PROOF STEP]
have f6: "FSM.after M1 (FSM.initial M1) v = FSM.after M1 (FSM.initial M1) v''"
[PROOF STATE]
proof (prove)
using this:
v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')

goal (1 subgoal):
 1. after_initial M1 v = after_initial M1 v''
[PROOF STEP]
using f4 \<open>converge M1 v v''\<close> assms(1) assms(3)
[PROOF STATE]
proof (prove)
using this:
v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')
\<forall>f ps psa. \<not> minimal f \<or> \<not> observable f \<or> ps \<notin> L f \<or> psa \<notin> L f \<or> converge f ps psa = (after_initial f ps = after_initial f psa)
converge M1 v v''
observable M1
minimal M1

goal (1 subgoal):
 1. after_initial M1 v = after_initial M1 v''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
after_initial M1 v = after_initial M1 v''

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
have "FSM.after M1 (FSM.initial M1) u = FSM.after M1 (FSM.initial M1) u''"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 u = after_initial M1 u''
[PROOF STEP]
using f4 f3 \<open>converge M1 u u''\<close> assms(1) assms(3)
[PROOF STATE]
proof (prove)
using this:
\<forall>f ps psa. \<not> minimal f \<or> \<not> observable f \<or> ps \<notin> L f \<or> psa \<notin> L f \<or> converge f ps psa = (after_initial f ps = after_initial f psa)
u \<in> L M1 \<and> u'' \<in> L M1 \<and> LS M1 (after_initial M1 u) = LS M1 (after_initial M1 u'')
converge M1 u u''
observable M1
minimal M1

goal (1 subgoal):
 1. after_initial M1 u = after_initial M1 u''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
after_initial M1 u = after_initial M1 u''

goal (1 subgoal):
 1. \<lbrakk>FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y; converge M1 u u''; converge M1 v v''\<rbrakk> \<Longrightarrow> after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
after_initial M1 u = after_initial M1 u''
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u = after_initial M1 u''

goal (1 subgoal):
 1. after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
using f6 f5 f3 a1
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u = after_initial M1 u''
after_initial M1 v = after_initial M1 v''
v \<in> L M1 \<and> v'' \<in> L M1 \<and> LS M1 (after_initial M1 v) = LS M1 (after_initial M1 v'')
u \<in> L M1 \<and> u'' \<in> L M1 \<and> LS M1 (after_initial M1 u) = LS M1 (after_initial M1 u'')
FSM.h_obs M1 (after_initial M1 u) x y \<noteq> FSM.h_obs M1 (after_initial M1 v) x y

goal (1 subgoal):
 1. after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])
[PROOF STEP]
by (metis (no_types) \<open>u'' @ [(x, y)] \<in> L M1\<close> \<open>v'' @ [(x, y)] \<in> L M1\<close> after_h_obs after_language_iff after_split assms(1) h_obs_from_LS)
[PROOF STATE]
proof (state)
this:
after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
after_initial M1 (u'' @ [(x, y)]) \<noteq> after_initial M1 (v'' @ [(x, y)])

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
obtain e' w' where "get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u''@[(x,y)]) (v''@[(x,y)]) k = (e',w')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>e' w'. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w') \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using prod.exhaust
[PROOF STATE]
proof (prove)
using this:
(\<And>x1 x2. ?y = (x1, x2) \<Longrightarrow> ?P) \<Longrightarrow> ?P

goal (1 subgoal):
 1. (\<And>e' w'. get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w') \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')
[PROOF STEP]
have "tryIO (e,w) (x,y) = (if e' = 0 then (0,[]) else if e' \<le> e then (e',(x,y)#w') else (e,w))"
[PROOF STATE]
proof (prove)
using this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (if e' = 0 then (0, []) else if e' \<le> e then (e', (x, y) # w') else (e, w))
[PROOF STEP]
using \<open>get_extension T G cg_lookup u' x y = Some u''\<close> Some False \<open>\<not> (h_obs M1 su x y = None) \<noteq> (h_obs M1 sv x y = None)\<close> \<open>e \<noteq> 0\<close>
[PROOF STATE]
proof (prove)
using this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')
get_extension T G cg_lookup u' x y = Some u''
get_extension T G cg_lookup v' x y = Some v''
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y
\<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)
e \<noteq> 0

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (if e' = 0 then (0, []) else if e' \<le> e then (e', (x, y) # w') else (e, w))
[PROOF STEP]
unfolding tryIO Let_def
[PROOF STATE]
proof (prove)
using this:
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')
get_extension T G cg_lookup u' x y = Some u''
get_extension T G cg_lookup v' x y = Some v''
FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y
\<not> (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None)
e \<noteq> 0

goal (1 subgoal):
 1. (case (e, w) of (minEst, bestPrefix) \<Rightarrow> \<lambda>(x, y). if minEst = 0 then (minEst, bestPrefix) else case get_extension T G cg_lookup u' x y of None \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> (minEst, bestPrefix) | Some v'' \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup v'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (v'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length v' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup u' then length u' else 0), [(x, y)]) else (minEst, bestPrefix) | Some u'' \<Rightarrow> case get_extension T G cg_lookup v' x y of None \<Rightarrow> if (if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0) \<le> minEst then ((if estimate_growth M1 get_distinguishing_trace su sv x y errorValue \<noteq> 1 then if has_leaf T G cg_lookup u'' then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + 1 else if \<not> has_leaf T G cg_lookup (u'' @ [(x, y)]) then estimate_growth M1 get_distinguishing_trace su sv x y errorValue + length u' + 1 else estimate_growth M1 get_distinguishing_trace su sv x y errorValue else estimate_growth M1 get_distinguishing_trace su sv x y errorValue) + (if \<not> has_leaf T G cg_lookup v' then length v' else 0), [(x, y)]) else (minEst, bestPrefix) | Some v'' \<Rightarrow> if (FSM.h_obs M1 su x y = None) \<noteq> (FSM.h_obs M1 sv x y = None) then (0, []) else if FSM.h_obs M1 su x y = FSM.h_obs M1 sv x y then (minEst, bestPrefix) else case get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k of (e, w) \<Rightarrow> if e = 0 then (0, []) else if e \<le> minEst then (e, (x, y) # w) else (minEst, bestPrefix)) (x, y) = (if e' = 0 then (0, []) else if e' \<le> e then (e', (x, y) # w') else (e, w))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (if e' = 0 then (0, []) else if e' \<le> e then (e', (x, y) # w') else (e, w))

goal (1 subgoal):
 1. FSM.h_obs M1 su x y \<noteq> FSM.h_obs M1 sv x y \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "e' = 0")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. e' = 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. e' \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
e' = 0

goal (2 subgoals):
 1. e' = 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. e' \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "\<not> converge M2 u v"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
note \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close>
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
[PROOF STEP]
have "u' \<in> L M2" and "v' \<in> L M2"
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. u' \<in> L M2 &&& v' \<in> L M2
[PROOF STEP]
using \<open>\<not> (\<not> isin T u' \<or> \<not> isin T v')\<close> \<open>u' \<in> L M1\<close> \<open>v' \<in> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
\<not> (\<not> isin T u' \<or> \<not> isin T v')
u' \<in> L M1
v' \<in> L M1

goal (1 subgoal):
 1. u' \<in> L M2 &&& v' \<in> L M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
u' \<in> L M2
v' \<in> L M2

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
have "u'' \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u'' \<in> L M2
[PROOF STEP]
using \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close> \<open>u'' \<in> set T \<inter> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
u'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. u'' \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
u'' \<in> L M2

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
u'' \<in> L M2
[PROOF STEP]
have "converge M2 u' u''"
[PROOF STATE]
proof (prove)
using this:
u'' \<in> L M2

goal (1 subgoal):
 1. converge M2 u' u''
[PROOF STEP]
using get_extension_result(2)[OF \<open>u' \<in> L M1\<close> \<open>u' \<in> L M2\<close> assms(10) \<open>get_extension T G cg_lookup u' x y = Some u''\<close>]
[PROOF STATE]
proof (prove)
using this:
u'' \<in> L M2
u'' \<in> L M2 \<Longrightarrow> converge M2 u' u''

goal (1 subgoal):
 1. converge M2 u' u''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
converge M2 u' u''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
converge M2 u' u''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
note \<open>converge M2 u u'\<close>
[PROOF STATE]
proof (state)
this:
converge M2 u u'

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
converge M2 u' u''
converge M2 u u'
[PROOF STEP]
have "converge M2 u u''"
[PROOF STATE]
proof (prove)
using this:
converge M2 u' u''
converge M2 u u'

goal (1 subgoal):
 1. converge M2 u u''
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
converge M2 u u''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
have "v'' \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. v'' \<in> L M2
[PROOF STEP]
using \<open>L M1 \<inter> set T = L M2 \<inter> set T\<close> \<open>v'' \<in> set T \<inter> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
v'' \<in> Prefix_Tree.set T \<inter> L M1

goal (1 subgoal):
 1. v'' \<in> L M2
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
v'' \<in> L M2

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
v'' \<in> L M2
[PROOF STEP]
have "converge M2 v' v''"
[PROOF STATE]
proof (prove)
using this:
v'' \<in> L M2

goal (1 subgoal):
 1. converge M2 v' v''
[PROOF STEP]
using get_extension_result(2)[OF \<open>v' \<in> L M1\<close> \<open>v' \<in> L M2\<close> assms(10) \<open>get_extension T G cg_lookup v' x y = Some v''\<close>]
[PROOF STATE]
proof (prove)
using this:
v'' \<in> L M2
v'' \<in> L M2 \<Longrightarrow> converge M2 v' v''

goal (1 subgoal):
 1. converge M2 v' v''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
converge M2 v' v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
converge M2 v' v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
note \<open>converge M2 v v'\<close>
[PROOF STATE]
proof (state)
this:
converge M2 v v'

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
converge M2 v' v''
converge M2 v v'
[PROOF STEP]
have "converge M2 v v''"
[PROOF STATE]
proof (prove)
using this:
converge M2 v' v''
converge M2 v v'

goal (1 subgoal):
 1. converge M2 v v''
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
converge M2 v v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
have "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0
[PROOF STEP]
using True \<open>get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u''@[(x,y)]) (v''@[(x,y)]) k = (e',w')\<close>
[PROOF STATE]
proof (prove)
using this:
e' = 0
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0
[PROOF STEP]
have "\<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])"
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0

goal (1 subgoal):
 1. \<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])
[PROOF STEP]
using Suc.IH[OF \<open>u''@[(x,y)] \<in> L M1\<close> \<open>u''@[(x,y)] \<in> L M2\<close> \<open>v''@[(x,y)] \<in> L M1\<close> \<open>v''@[(x,y)] \<in> L M2\<close> \<open>FSM.after M1 (FSM.initial M1) (u'' @ [(x, y)]) \<noteq> FSM.after M1 (FSM.initial M1) (v'' @ [(x, y)])\<close>]
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0 \<longrightarrow> \<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)))

goal (1 subgoal):
 1. \<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])
[PROOF STEP]
using \<open>L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T\<close>
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0 \<longrightarrow> \<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)))
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T

goal (1 subgoal):
 1. \<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])
[PROOF STEP]
have "\<not> converge M2 u'' v''"
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])

goal (1 subgoal):
 1. \<not> converge M2 u'' v''
[PROOF STEP]
using diverge_prefix[OF assms(2) \<open>u''@[(x,y)] \<in> L M2\<close> \<open>v''@[(x,y)] \<in> L M2\<close>]
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])
\<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)]) \<Longrightarrow> \<not> converge M2 u'' v''

goal (1 subgoal):
 1. \<not> converge M2 u'' v''
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<not> converge M2 u'' v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> converge M2 u'' v''
[PROOF STEP]
show "\<not> converge M2 u v"
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u'' v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
using \<open>converge M2 u u''\<close> \<open>converge M2 v v''\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u'' v''
converge M2 u u''
converge M2 v v''

goal (1 subgoal):
 1. \<not> converge M2 u v
[PROOF STEP]
by fastforce
[PROOF STATE]
proof (state)
this:
\<not> converge M2 u v

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<not> converge M2 u v

goal (2 subgoals):
 1. e' = 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. e' \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> converge M2 u v
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u v

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
unfolding P \<open>tryIO (e,w) (x,y) = (if e' = 0 then (0,[]) else if e' \<le> e then (e',(x,y)#w') else (e,w))\<close> True fst_conv snd_conv su sv
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u v

goal (1 subgoal):
 1. ((fst (if 0 = 0 then (0, []) else if 0 \<le> e then (0, (x, y) # w') else (e, w)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (if 0 = 0 then (0, []) else if 0 \<le> e then (0, (x, y) # w') else (e, w)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (if 0 = 0 then (0, []) else if 0 \<le> e then (0, (x, y) # w') else (e, w)) @ \<gamma>)))) \<and> fst (if 0 = 0 then (0, []) else if 0 \<le> e then (0, (x, y) # w') else (e, w)) \<le> e
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. e' \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. e' \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
e' \<noteq> 0

goal (1 subgoal):
 1. e' \<noteq> 0 \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
proof (cases "e' \<le> e")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
e' \<le> e

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
e' \<le> e
[PROOF STEP]
have "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0"
[PROOF STATE]
proof (prove)
using this:
e' \<le> e

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0
[PROOF STEP]
using \<open>get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u''@[(x,y)]) (v''@[(x,y)]) k = (e',w')\<close> False
[PROOF STATE]
proof (prove)
using this:
e' \<le> e
get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k = (e', w')
e' \<noteq> 0

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0
[PROOF STEP]
have "(\<exists>\<gamma>. distinguishes M1 (FSM.after M1 (FSM.initial M1) (u'' @ [(x, y)])) (FSM.after M1 (FSM.initial M1) (v'' @ [(x, y)]))
                                     (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>))"
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0

goal (1 subgoal):
 1. \<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)
[PROOF STEP]
using Suc.IH[OF \<open>u''@[(x,y)] \<in> L M1\<close> \<open>u''@[(x,y)] \<in> L M2\<close> \<open>v''@[(x,y)] \<in> L M1\<close> \<open>v''@[(x,y)] \<in> L M2\<close> \<open>FSM.after M1 (FSM.initial M1) (u'' @ [(x, y)]) \<noteq> FSM.after M1 (FSM.initial M1) (v'' @ [(x, y)])\<close>]
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) = 0 \<longrightarrow> \<not> converge M2 (u'' @ [(x, y)]) (v'' @ [(x, y)])) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)))

goal (1 subgoal):
 1. \<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)
[PROOF STEP]
obtain \<gamma> where "distinguishes M1 (FSM.after M1 (FSM.initial M1) (u'' @ [(x, y)])) (FSM.after M1 (FSM.initial M1) (v'' @ [(x, y)])) (w'@\<gamma>)"
[PROOF STATE]
proof (prove)
using this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u'' @ [(x, y)]) (v'' @ [(x, y)]) k) @ \<gamma>)

goal (1 subgoal):
 1. (\<And>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (w' @ \<gamma>) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
unfolding \<open>get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace (u''@[(x,y)]) (v''@[(x,y)]) k = (e',w')\<close>  snd_conv
[PROOF STATE]
proof (prove)
using this:
\<exists>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (w' @ \<gamma>)

goal (1 subgoal):
 1. (\<And>\<gamma>. distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (w' @ \<gamma>) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (w' @ \<gamma>)

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "distinguishes M1 (after_initial M1 u'') (after_initial M1 v'')  ((x,y)#(w'@\<gamma>))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u'') (after_initial M1 v'') ((x, y) # w' @ \<gamma>)
[PROOF STEP]
using distinguishes_after_initial_prepend[OF assms(1) language_prefix[OF \<open>u''@[(x,y)] \<in> L M1\<close>] language_prefix[OF \<open>v''@[(x,y)] \<in> L M1\<close>]]
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>FSM.h_obs M1 (after_initial M1 u'') ?x ?y \<noteq> None; FSM.h_obs M1 (after_initial M1 v'') ?x ?y \<noteq> None; distinguishes M1 (after_initial M1 (u'' @ [(?x, ?y)])) (after_initial M1 (v'' @ [(?x, ?y)])) ?\<gamma>\<rbrakk> \<Longrightarrow> distinguishes M1 (after_initial M1 u'') (after_initial M1 v'') ((?x, ?y) # ?\<gamma>)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u'') (after_initial M1 v'') ((x, y) # w' @ \<gamma>)
[PROOF STEP]
by (metis Suc.prems(1) Suc.prems(3) \<open>converge M1 u u'\<close> \<open>converge M1 u' u''\<close> \<open>converge M1 v v''\<close> \<open>distinguishes M1 (after_initial M1 (u'' @ [(x, y)])) (after_initial M1 (v'' @ [(x, y)])) (w' @ \<gamma>)\<close> \<open>h_obs M1 su x y \<noteq> None\<close> \<open>h_obs M1 sv x y \<noteq> None\<close> \<open>u' \<in> L M1\<close> \<open>u'' @ [(x, y)] \<in> L M1\<close> \<open>v'' @ [(x, y)] \<in> L M1\<close> assms(1) assms(3) convergence_minimal language_prefix su sv)
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u'') (after_initial M1 v'') ((x, y) # w' @ \<gamma>)

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
distinguishes M1 (after_initial M1 u'') (after_initial M1 v'') ((x, y) # w' @ \<gamma>)
[PROOF STEP]
have "distinguishes M1 (after_initial M1 u) (after_initial M1 v)  (((x,y)#w')@\<gamma>)"
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u'') (after_initial M1 v'') ((x, y) # w' @ \<gamma>)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (((x, y) # w') @ \<gamma>)
[PROOF STEP]
by (metis Cons_eq_appendI Suc.prems(1) Suc.prems(3) \<open>converge M1 u u''\<close> \<open>converge M1 v v''\<close> \<open>u'' @ [(x, y)] \<in> L M1\<close> \<open>v'' @ [(x, y)] \<in> L M1\<close> assms(1) assms(3) convergence_minimal language_prefix)
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) (((x, y) # w') @ \<gamma>)

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
have "tryIO (e,w) (x,y) = (e',(x,y)#w')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e', (x, y) # w')
[PROOF STEP]
using \<open>tryIO (e,w) (x,y) = (if e' = 0 then (0,[]) else if e' \<le> e then (e',(x,y)#w') else (e,w))\<close> True False
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (if e' = 0 then (0, []) else if e' \<le> e then (e', (x, y) # w') else (e, w))
e' \<le> e
e' \<noteq> 0

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e', (x, y) # w')
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (e', (x, y) # w')

goal (2 subgoals):
 1. e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
 2. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
unfolding P \<open>tryIO (e,w) (x,y) = (e',(x,y)#w')\<close> fst_conv snd_conv
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. ((e' = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (e' \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (((x, y) # w') @ \<gamma>)))) \<and> e' \<le> e
[PROOF STEP]
using \<open>distinguishes M1 (after_initial M1 u) (after_initial M1 v) (((x,y)#w')@\<gamma>)\<close>
                              False True
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 v) (((x, y) # w') @ \<gamma>)
e' \<noteq> 0
e' \<le> e

goal (1 subgoal):
 1. ((e' = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (e' \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (((x, y) # w') @ \<gamma>)))) \<and> e' \<le> e
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal (1 subgoal):
 1. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> e' \<le> e

goal (1 subgoal):
 1. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> e' \<le> e
[PROOF STEP]
have "tryIO (e,w) (x,y) = (e,w)"
[PROOF STATE]
proof (prove)
using this:
\<not> e' \<le> e

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
using \<open>e' \<noteq> 0\<close> \<open>tryIO (e,w) (x,y) = (if e' = 0 then (0,[]) else if e' \<le> e then (e',(x,y)#w') else (e,w))\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> e' \<le> e
e' \<noteq> 0
tryIO (e, w) (x, y) = (if e' = 0 then (0, []) else if e' \<le> e then (e', (x, y) # w') else (e, w))

goal (1 subgoal):
 1. tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
tryIO (e, w) (x, y) = (e, w)

goal (1 subgoal):
 1. \<not> e' \<le> e \<Longrightarrow> P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
tryIO (e, w) (x, y) = (e, w)
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
using \<open>P (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
tryIO (e, w) (x, y) = (e, w)
P (e, w)

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> e

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<lbrakk>?e < errorValue; P (?e, ?w)\<rbrakk> \<Longrightarrow> P (tryIO (?e, ?w) (?x, ?y)) \<and> fst (tryIO (?e, ?w) (?x, ?y)) \<le> ?e

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "minEst0 < errorValue"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. minEst0 < errorValue
[PROOF STEP]
unfolding errorValue
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. minEst0 < Suc minEst0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
minEst0 < errorValue

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
have "P (foldl tryIO (minEst0,[]) XY) \<and> fst (foldl tryIO (minEst0,[]) XY) \<le> minEst0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0
[PROOF STEP]
proof (induction XY rule: rev_induct)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. P (foldl tryIO (minEst0, []) []) \<and> fst (foldl tryIO (minEst0, []) []) \<le> minEst0
 2. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
case Nil
[PROOF STATE]
proof (state)
this:

goal (2 subgoals):
 1. P (foldl tryIO (minEst0, []) []) \<and> fst (foldl tryIO (minEst0, []) []) \<le> minEst0
 2. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (foldl tryIO (minEst0, []) []) \<and> fst (foldl tryIO (minEst0, []) []) \<le> minEst0
[PROOF STEP]
using \<open>P (minEst0,[])\<close>
[PROOF STATE]
proof (prove)
using this:
P (minEst0, [])

goal (1 subgoal):
 1. P (foldl tryIO (minEst0, []) []) \<and> fst (foldl tryIO (minEst0, []) []) \<le> minEst0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (foldl tryIO (minEst0, []) []) \<and> fst (foldl tryIO (minEst0, []) []) \<le> minEst0

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
case (snoc a XY)
[PROOF STATE]
proof (state)
this:
P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
obtain x y where "a = (x,y)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>x y. a = (x, y) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using prod.exhaust
[PROOF STATE]
proof (prove)
using this:
(\<And>x1 x2. ?y = (x1, x2) \<Longrightarrow> ?P) \<Longrightarrow> ?P

goal (1 subgoal):
 1. (\<And>x y. a = (x, y) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
a = (x, y)

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
a = (x, y)

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
obtain e w where "(foldl tryIO (minEst0,[]) XY) = (e,w)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>e w. foldl tryIO (minEst0, []) XY = (e, w) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using prod.exhaust
[PROOF STATE]
proof (prove)
using this:
(\<And>x1 x2. ?y = (x1, x2) \<Longrightarrow> ?P) \<Longrightarrow> ?P

goal (1 subgoal):
 1. (\<And>e w. foldl tryIO (minEst0, []) XY = (e, w) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
foldl tryIO (minEst0, []) XY = (e, w)

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
a = (x, y)
foldl tryIO (minEst0, []) XY = (e, w)
[PROOF STEP]
have "(foldl tryIO (minEst0, []) (XY@[a])) = tryIO (e,w) (x,y)"
[PROOF STATE]
proof (prove)
using this:
a = (x, y)
foldl tryIO (minEst0, []) XY = (e, w)

goal (1 subgoal):
 1. foldl tryIO (minEst0, []) (XY @ [a]) = tryIO (e, w) (x, y)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
foldl tryIO (minEst0, []) (XY @ [a]) = tryIO (e, w) (x, y)

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
have "P (e,w)" and "e \<le> minEst0" and "e < errorValue"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P (e, w) &&& e \<le> minEst0 &&& e < errorValue
[PROOF STEP]
using snoc.IH \<open>minEst0 < errorValue\<close>
[PROOF STATE]
proof (prove)
using this:
P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0
minEst0 < errorValue

goal (1 subgoal):
 1. P (e, w) &&& e \<le> minEst0 &&& e < errorValue
[PROOF STEP]
unfolding \<open>(foldl tryIO (minEst0,[]) XY) = (e,w)\<close>
[PROOF STATE]
proof (prove)
using this:
P (e, w) \<and> fst (e, w) \<le> minEst0
minEst0 < errorValue

goal (1 subgoal):
 1. P (e, w) &&& e \<le> minEst0 &&& e < errorValue
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
P (e, w)
e \<le> minEst0
e < errorValue

goal (1 subgoal):
 1. \<And>x xs. P (foldl tryIO (minEst0, []) xs) \<and> fst (foldl tryIO (minEst0, []) xs) \<le> minEst0 \<Longrightarrow> P (foldl tryIO (minEst0, []) (xs @ [x])) \<and> fst (foldl tryIO (minEst0, []) (xs @ [x])) \<le> minEst0
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
P (e, w)
e \<le> minEst0
e < errorValue
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
using this:
P (e, w)
e \<le> minEst0
e < errorValue

goal (1 subgoal):
 1. P (foldl tryIO (minEst0, []) (XY @ [a])) \<and> fst (foldl tryIO (minEst0, []) (XY @ [a])) \<le> minEst0
[PROOF STEP]
unfolding \<open>(foldl tryIO (minEst0, []) (XY@[a])) = tryIO (e,w) (x,y)\<close>
[PROOF STATE]
proof (prove)
using this:
P (e, w)
e \<le> minEst0
e < errorValue

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> minEst0
[PROOF STEP]
using \<open>\<And> x y e w . e < errorValue \<Longrightarrow> P (e,w) \<Longrightarrow> P (tryIO (e,w) (x,y)) \<and> fst (tryIO (e,w) (x,y)) \<le> e\<close>
[PROOF STATE]
proof (prove)
using this:
P (e, w)
e \<le> minEst0
e < errorValue
\<lbrakk>?e < errorValue; P (?e, ?w)\<rbrakk> \<Longrightarrow> P (tryIO (?e, ?w) (?x, ?y)) \<and> fst (tryIO (?e, ?w) (?x, ?y)) \<le> ?e

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> minEst0
[PROOF STEP]
using dual_order.trans
[PROOF STATE]
proof (prove)
using this:
P (e, w)
e \<le> minEst0
e < errorValue
\<lbrakk>?e < errorValue; P (?e, ?w)\<rbrakk> \<Longrightarrow> P (tryIO (?e, ?w) (?x, ?y)) \<and> fst (tryIO (?e, ?w) (?x, ?y)) \<le> ?e
\<lbrakk>?b \<le> ?a; ?c \<le> ?b\<rbrakk> \<Longrightarrow> ?c \<le> ?a

goal (1 subgoal):
 1. P (tryIO (e, w) (x, y)) \<and> fst (tryIO (e, w) (x, y)) \<le> minEst0
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
P (foldl tryIO (minEst0, []) (XY @ [a])) \<and> fst (foldl tryIO (minEst0, []) (XY @ [a])) \<le> minEst0

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0
[PROOF STEP]
have "P (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k))"
[PROOF STATE]
proof (prove)
using this:
P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0

goal (1 subgoal):
 1. P (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k))
[PROOF STEP]
unfolding res
[PROOF STATE]
proof (prove)
using this:
P (foldl tryIO (minEst0, []) XY) \<and> fst (foldl tryIO (minEst0, []) XY) \<le> minEst0

goal (1 subgoal):
 1. P (foldl tryIO (minEst0, []) XY)
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
P (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k))

goal (1 subgoal):
 1. \<not> (\<not> isin T u' \<or> \<not> isin T v') \<Longrightarrow> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
P (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
P (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k))

goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
unfolding P
[PROOF STATE]
proof (prove)
using this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))

goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v (Suc k)) @ \<gamma>)))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)))

goal (2 subgoals):
 1. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v
 2. fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)))
[PROOF STEP]
show "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v"
       and  "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow>  \<exists> \<gamma> . distinguishes M1 (after_initial M1 u) (after_initial M1 v) ((snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))@\<gamma>)"
[PROOF STATE]
proof (prove)
using this:
(fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<longrightarrow> \<not> converge M2 u v) \<and> (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<longrightarrow> (\<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)))

goal (1 subgoal):
 1. (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v) &&& (fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>))
[PROOF STEP]
by blast+
[PROOF STATE]
proof (state)
this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 \<Longrightarrow> \<not> converge M2 u v
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) \<noteq> 0 \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 v) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ \<gamma>)

goal:
No subgoals!
[PROOF STEP]
qed