[STATEMENT]
lemma spyh_distinguish_establishes_divergence :
  fixes M1 :: "('a::linorder,'b::linorder,'c::linorder) fsm"
  assumes "observable M1"
  and     "observable M2"
  and     "minimal M1"
  and     "minimal M2"
  and     "u \<in> L M1" and "u \<in> L M2"
  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     "convergence_graph_insert_invar M1 M2 cg_lookup cg_insert"
  and     "list.set X \<subseteq> L M1"
  and     "list.set X \<subseteq> L M2"
  and     "L M1 \<inter> set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))"
  and     "\<And> T w u' uBest lBest . fst (append_heuristic T w (uBest,lBest) u') \<in> {u',uBest}"
shows "\<forall> v . v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v"
(is "?P1 X")
and   "convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))"
(is "?P2 X")
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v &&& convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
have "?P1 X \<and> ?P2 X"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
using assms(10,11,12)
[PROOF STATE]
proof (prove)
using this:
list.set X \<subseteq> L M1
list.set X \<subseteq> L M2
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
proof (induction X rule: rev_induct)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<lbrakk>list.set [] \<subseteq> L M1; list.set [] \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))
 2. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
case Nil
[PROOF STATE]
proof (state)
this:
list.set [] \<subseteq> L M1
list.set [] \<subseteq> L M2
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))

goal (2 subgoals):
 1. \<lbrakk>list.set [] \<subseteq> L M1; list.set [] \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))
 2. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have *: "spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic = (T,G)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic = (T, G)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic = (T, G)

goal (2 subgoals):
 1. \<lbrakk>list.set [] \<subseteq> L M1; list.set [] \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))
 2. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))
[PROOF STEP]
using Nil assms(8)
[PROOF STATE]
proof (prove)
using this:
list.set [] \<subseteq> L M1
list.set [] \<subseteq> L M2
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))
convergence_graph_lookup_invar M1 M2 cg_lookup G

goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))
[PROOF STEP]
unfolding * fst_conv snd_conv
[PROOF STATE]
proof (prove)
using this:
list.set [] \<subseteq> L M1
list.set [] \<subseteq> L M2
L M1 \<inter> Prefix_Tree.set T = L M2 \<inter> Prefix_Tree.set T
convergence_graph_lookup_invar M1 M2 cg_lookup G

goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup G
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(\<forall>v. v \<in> list.set [] \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u [] k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
case (snoc a X)
[PROOF STATE]
proof (state)
this:
\<lbrakk>list.set X \<subseteq> L M1; list.set X \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
list.set (X @ [a]) \<subseteq> L M1
list.set (X @ [a]) \<subseteq> L M2
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
define dh where dh: "dh = (\<lambda> (T,G) v . if after_initial M1 u = after_initial M1 v
                                  then (T,G)
                                  else (let ew = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k
                                         in if fst ew = 0
                                              then (T,G)
                                              else (let u' = (u@(snd ew));
                                                        v' = (v@(snd ew));
                                                        w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 v) (snd ew) then (snd ew) else (snd ew)@(get_distinguishing_trace (after_initial M1 u') (after_initial M1 v')));
                                                        TG' = distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic
                                                    in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert v w' completeInputTraces append_heuristic)))"
[PROOF STATE]
proof (state)
this:
dh = (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else let ew = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k in if fst ew = 0 then (T, G) else let u' = u @ snd ew; v' = v @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 v) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert v w' completeInputTraces append_heuristic)

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic
                = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a
[PROOF STEP]
unfolding dh spyh_distinguish.simps Let_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) (T, G) (X @ [a]) = (case foldl (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) (T, G) X of (T, G) \<Rightarrow> \<lambda>v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) a
[PROOF STEP]
unfolding foldl_append
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. foldl (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) (foldl (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) (T, G) X) [a] = (case foldl (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) (T, G) X of (T, G) \<Rightarrow> \<lambda>v. if after_initial M1 u = after_initial M1 v then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert v (if does_distinguish 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)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k))) (after_initial M1 (v @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k)))) completeInputTraces append_heuristic) a
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "\<And> T G . set T \<subseteq> set (fst (dh (T,G) a))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>T G. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>T G. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
fix T G
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>T G. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
show "set T \<subseteq> set (fst (dh (T,G) a))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
proof (cases "after_initial M1 u = after_initial M1 a")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. after_initial M1 u = after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
 2. after_initial M1 u \<noteq> after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
after_initial M1 u = after_initial M1 a

goal (2 subgoals):
 1. after_initial M1 u = after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
 2. after_initial M1 u \<noteq> after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
after_initial M1 u = after_initial M1 a
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u = after_initial M1 a

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
using dh
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u = after_initial M1 a
dh = (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else let ew = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k in if fst ew = 0 then (T, G) else let u' = u @ snd ew; v' = v @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 v) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert v w' completeInputTraces append_heuristic)

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))

goal (1 subgoal):
 1. after_initial M1 u \<noteq> after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. after_initial M1 u \<noteq> after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
after_initial M1 u \<noteq> after_initial M1 a

goal (1 subgoal):
 1. after_initial M1 u \<noteq> after_initial M1 a \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u \<noteq> after_initial M1 a

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
proof (cases "fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
 2. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0

goal (2 subgoals):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
 2. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
using False dh
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0
after_initial M1 u \<noteq> after_initial M1 a
dh = (\<lambda>(T, G) v. if after_initial M1 u = after_initial M1 v then (T, G) else let ew = get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u v k in if fst ew = 0 then (T, G) else let u' = u @ snd ew; v' = v @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 v) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert v w' completeInputTraces append_heuristic)

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
define u' where u': "u' = (u@(snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))"
[PROOF STATE]
proof (state)
this:
u' = u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
define v' where v': "v' = (a@(snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))"
[PROOF STATE]
proof (state)
this:
v' = a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
define w where w: "w = get_distinguishing_trace (after_initial M1 u') (after_initial M1 v')"
[PROOF STATE]
proof (state)
this:
w = get_distinguishing_trace (after_initial M1 u') (after_initial M1 v')

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
define w' where w': "w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) else (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))@w)"
[PROOF STATE]
proof (state)
this:
w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ w)

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
define TG' where TG': "TG' = distribute_extension M1 T G cg_lookup cg_insert u w'"
[PROOF STATE]
proof (state)
this:
TG' = distribute_extension M1 T G cg_lookup cg_insert u w'

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
have "dh (T,G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. dh (T, G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic
[PROOF STEP]
using False \<open>FSM.after M1 (FSM.initial M1) u \<noteq> FSM.after M1 (FSM.initial M1) a\<close>
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0
after_initial M1 u \<noteq> after_initial M1 a

goal (1 subgoal):
 1. dh (T, G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic
[PROOF STEP]
unfolding dh u' v' w w' TG' Let_def case_prod_conv
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0
after_initial M1 u \<noteq> after_initial M1 a

goal (1 subgoal):
 1. (if after_initial M1 u = after_initial M1 a then (T, G) else if fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) = 0 then (T, G) else distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))) (after_initial M1 (a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))) (after_initial M1 (a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))) (after_initial M1 (a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))) completeInputTraces append_heuristic) = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))) (after_initial M1 (a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))) (after_initial M1 (a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)) then snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) else snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) @ get_distinguishing_trace (after_initial M1 (u @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k))) (after_initial M1 (a @ snd (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k)))) completeInputTraces append_heuristic
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
dh (T, G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic

goal (1 subgoal):
 1. \<lbrakk>after_initial M1 u \<noteq> after_initial M1 a; fst (get_prefix_of_separating_sequence M1 T G cg_lookup get_distinguishing_trace u a k) \<noteq> 0\<rbrakk> \<Longrightarrow> Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
dh (T, G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
dh (T, G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
using distribute_extension_subset
[PROOF STATE]
proof (prove)
using this:
dh (T, G) a = distribute_extension M1 (fst (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) (snd (distribute_extension M1 T G cg_lookup cg_insert u w' completeInputTraces append_heuristic)) cg_lookup cg_insert a w' completeInputTraces append_heuristic
Prefix_Tree.set ?T \<subseteq> Prefix_Tree.set (fst (distribute_extension ?M ?T ?G ?cg_lookup ?cg_insert ?u ?w ?b ?heuristic))

goal (1 subgoal):
 1. Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))
[PROOF STEP]
by (metis (no_types, lifting) subset_trans)
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set T \<subseteq> Prefix_Tree.set (fst (dh (T, G) a))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set ?T \<subseteq> Prefix_Tree.set (fst (dh (?T, ?G) a))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
Prefix_Tree.set ?T \<subseteq> Prefix_Tree.set (fst (dh (?T, ?G) a))
[PROOF STEP]
have "set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic))"
[PROOF STATE]
proof (prove)
using this:
Prefix_Tree.set ?T \<subseteq> Prefix_Tree.set (fst (dh (?T, ?G) a))

goal (1 subgoal):
 1. Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
unfolding \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a\<close>
[PROOF STATE]
proof (prove)
using this:
Prefix_Tree.set ?T \<subseteq> Prefix_Tree.set (fst (dh (?T, ?G) a))

goal (1 subgoal):
 1. Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a))
[PROOF STEP]
by (metis prod.exhaust_sel)
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))"
[PROOF STATE]
proof (prove)
using this:
Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
using snoc.prems(3)
[PROOF STATE]
proof (prove)
using this:
Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "list.set X \<subseteq> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. list.set X \<subseteq> L M1
[PROOF STEP]
using snoc.prems(1)
[PROOF STATE]
proof (prove)
using this:
list.set (X @ [a]) \<subseteq> L M1

goal (1 subgoal):
 1. list.set X \<subseteq> L M1
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
list.set X \<subseteq> L M1

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
list.set X \<subseteq> L M1

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "list.set X \<subseteq> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. list.set X \<subseteq> L M2
[PROOF STEP]
using snoc.prems(2)
[PROOF STATE]
proof (prove)
using this:
list.set (X @ [a]) \<subseteq> L M2

goal (1 subgoal):
 1. list.set X \<subseteq> L M2
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
list.set X \<subseteq> L M2

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
list.set X \<subseteq> L M1
list.set X \<subseteq> L M2
[PROOF STEP]
have "?P1 X" and "?P2 X"
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
list.set X \<subseteq> L M1
list.set X \<subseteq> L M2

goal (1 subgoal):
 1. \<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v &&& convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
using snoc.IH
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
list.set X \<subseteq> L M1
list.set X \<subseteq> L M2
\<lbrakk>list.set X \<subseteq> L M1; list.set X \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v &&& convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
by blast+
[PROOF STATE]
proof (state)
this:
\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
obtain T' G' where "(spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) = (T',G')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>T' G'. spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G') \<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>T' G'. spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G') \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')
[PROOF STEP]
have "convergence_graph_lookup_invar M1 M2 cg_lookup G'"
[PROOF STATE]
proof (prove)
using this:
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup G'
[PROOF STEP]
using \<open>?P2 X\<close>
[PROOF STATE]
proof (prove)
using this:
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup G'
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
convergence_graph_lookup_invar M1 M2 cg_lookup G'

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "L M1 \<inter> set T' = L M2 \<inter> set T'"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'
[PROOF STEP]
using \<open>L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))\<close>
            \<open>(spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) = (T',G')\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')

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

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "\<not>converge M1 u a \<Longrightarrow> \<not>converge M2 u a" and "?P2 (X@[a])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a) &&& convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "a \<in> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. a \<in> L M1
[PROOF STEP]
using snoc.prems(1)
[PROOF STATE]
proof (prove)
using this:
list.set (X @ [a]) \<subseteq> L M1

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

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
a \<in> L M1
[PROOF STEP]
have "\<not>converge M1 u a \<Longrightarrow> after_initial M1 u \<noteq> after_initial M1 a"
[PROOF STATE]
proof (prove)
using this:
a \<in> L M1

goal (1 subgoal):
 1. \<not> converge M1 u a \<Longrightarrow> after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
using \<open>u \<in> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
a \<in> L M1
u \<in> L M1

goal (1 subgoal):
 1. \<not> converge M1 u a \<Longrightarrow> after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
using assms(1) assms(3) convergence_minimal
[PROOF STATE]
proof (prove)
using this:
a \<in> L M1
u \<in> L M1
observable M1
minimal M1
\<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. \<not> converge M1 u a \<Longrightarrow> after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<not> converge M1 u a \<Longrightarrow> after_initial M1 u \<noteq> after_initial M1 a

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "a \<in> L M2"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. a \<in> L M2
[PROOF STEP]
using snoc.prems(2)
[PROOF STATE]
proof (prove)
using this:
list.set (X @ [a]) \<subseteq> L M2

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

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
define ew where ew: "ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k"
[PROOF STATE]
proof (state)
this:
ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "(\<not>converge M1 u a \<longrightarrow> \<not>converge M2 u a) \<and> ?P2 (X@[a])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
proof (cases "fst ew = 0")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
fst ew = 0

goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
fst ew = 0
[PROOF STEP]
have *: "fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) = 0"
[PROOF STATE]
proof (prove)
using this:
fst ew = 0

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) = 0
[PROOF STEP]
unfolding ew
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) = 0

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a 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 a k) = 0

goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T' \<Longrightarrow> \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<lbrakk>L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'; \<not> converge M1 u a\<rbrakk> \<Longrightarrow> \<not> converge M2 u a
[PROOF STEP]
using get_prefix_of_separating_sequence_result(1)[OF assms(1,2,3) \<open>u \<in> L M1\<close> \<open>u \<in> L M2\<close> \<open>a \<in> L M1\<close> \<open>a \<in> L M2\<close> \<open>\<not>converge M1 u a \<Longrightarrow> after_initial M1 u \<noteq> after_initial M1 a\<close> assms(7) \<open>convergence_graph_lookup_invar M1 M2 cg_lookup G'\<close> _ *]
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>\<not> converge M1 u a; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q1 \<in> FSM.states M1; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q2 \<in> FSM.states M1; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q1 \<noteq> q2; L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'\<rbrakk> \<Longrightarrow> \<not> converge M2 u a

goal (1 subgoal):
 1. \<lbrakk>L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'; \<not> converge M1 u a\<rbrakk> \<Longrightarrow> \<not> converge M2 u a
[PROOF STEP]
by fast
[PROOF STATE]
proof (state)
this:
\<lbrakk>L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'; \<not> converge M1 u a\<rbrakk> \<Longrightarrow> \<not> converge M2 u a

goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<lbrakk>L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'; \<not> converge M1 u a\<rbrakk> \<Longrightarrow> \<not> converge M2 u a
[PROOF STEP]
have "(\<not>converge M1 u a \<longrightarrow> \<not>converge M2 u a)"
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'; \<not> converge M1 u a\<rbrakk> \<Longrightarrow> \<not> converge M2 u a

goal (1 subgoal):
 1. \<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a
[PROOF STEP]
using \<open>L M1 \<inter> set T' = L M2 \<inter> set T'\<close>
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'; \<not> converge M1 u a\<rbrakk> \<Longrightarrow> \<not> converge M2 u a
L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'

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

goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "(snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic)) = (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic) = snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)
[PROOF STEP]
unfolding \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a\<close>
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd (dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a) = snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)
[PROOF STEP]
unfolding \<open>(spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) = (T',G')\<close>
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd (dh (T', G') a) = snd (T', G')
[PROOF STEP]
unfolding dh case_prod_conv snd_conv
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd (if after_initial M1 u = after_initial M1 a then (T', G') else let ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k in if fst ew = 0 then (T', G') else let u' = u @ snd ew; v' = a @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic) = G'
[PROOF STEP]
using True ew
[PROOF STATE]
proof (prove)
using this:
fst ew = 0
ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k

goal (1 subgoal):
 1. snd (if after_initial M1 u = after_initial M1 a then (T', G') else let ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k in if fst ew = 0 then (T', G') else let u' = u @ snd ew; v' = a @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic) = G'
[PROOF STEP]
by fastforce
[PROOF STATE]
proof (state)
this:
snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic) = snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)

goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic) = snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)
[PROOF STEP]
have "?P2 (X@[a])"
[PROOF STATE]
proof (prove)
using this:
snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic) = snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using \<open>?P2 X\<close>
[PROOF STATE]
proof (prove)
using this:
snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic) = snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic)
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (2 subgoals):
 1. fst ew = 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using \<open>(\<not>converge M1 u a \<longrightarrow> \<not>converge M2 u a)\<close>
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a

goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
fst ew \<noteq> 0

goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
fst ew \<noteq> 0
[PROOF STEP]
have *: "fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) \<noteq> 0"
[PROOF STATE]
proof (prove)
using this:
fst ew \<noteq> 0

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) \<noteq> 0
[PROOF STEP]
unfolding ew
[PROOF STATE]
proof (prove)
using this:
fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) \<noteq> 0

goal (1 subgoal):
 1. fst (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a 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 a k) \<noteq> 0

goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
define w where w: "w = get_distinguishing_trace (after_initial M1 (u@(snd ew))) (after_initial M1 (a@(snd ew)))"
[PROOF STATE]
proof (state)
this:
w = get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))

goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
define w' where w': "w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then (snd ew) else (snd ew)@w)"
[PROOF STATE]
proof (state)
this:
w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ w)

goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
define TG' where TG': "TG' = distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic"
[PROOF STATE]
proof (state)
this:
TG' = distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic

goal (1 subgoal):
 1. fst ew \<noteq> 0 \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
proof (cases "\<not> converge M1 u a")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
\<not> converge M1 u a

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> converge M1 u a
[PROOF STEP]
have "after_initial M1 u \<noteq> after_initial M1 a"
[PROOF STATE]
proof (prove)
using this:
\<not> converge M1 u a

goal (1 subgoal):
 1. after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
using \<open>u \<in> L M1\<close> \<open>a \<in> L M1\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> converge M1 u a
u \<in> L M1
a \<in> L M1

goal (1 subgoal):
 1. after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
using assms(1) assms(3) convergence_minimal
[PROOF STATE]
proof (prove)
using this:
\<not> converge M1 u a
u \<in> L M1
a \<in> L M1
observable M1
minimal M1
\<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. after_initial M1 u \<noteq> after_initial M1 a
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
after_initial M1 u \<noteq> after_initial M1 a

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
obtain \<gamma> where "distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
unfolding \<open>ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k\<close>
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) @ \<gamma>) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using get_prefix_of_separating_sequence_result(2)[OF assms(1,2,3) \<open>u \<in> L M1\<close> \<open>u \<in> L M2\<close> \<open>a \<in> L M1\<close> \<open>a \<in> L M2\<close> \<open>after_initial M1 u \<noteq> after_initial M1 a\<close> assms(7) \<open>convergence_graph_lookup_invar M1 M2 cg_lookup G'\<close> _ *]
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>\<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q1 \<in> FSM.states M1; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q2 \<in> FSM.states M1; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q1 \<noteq> q2; L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'\<rbrakk> \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) @ \<gamma>)

goal (1 subgoal):
 1. (\<And>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) @ \<gamma>) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[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:
\<lbrakk>\<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q1 \<in> FSM.states M1; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q2 \<in> FSM.states M1; \<And>\<alpha> \<beta> q1 q2. \<lbrakk>q1 \<in> FSM.states M1; q2 \<in> FSM.states M1; q1 \<noteq> q2\<rbrakk> \<Longrightarrow> q1 \<noteq> q2; L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'\<rbrakk> \<Longrightarrow> \<exists>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) @ \<gamma>)
L M1 \<inter> Prefix_Tree.set T' = L M2 \<inter> Prefix_Tree.set T'

goal (1 subgoal):
 1. (\<And>\<gamma>. distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd (get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k) @ \<gamma>) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "dh (T',G') a = distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. dh (T', G') a = distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic
[PROOF STEP]
unfolding dh w w' TG' case_prod_conv
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (if after_initial M1 u = after_initial M1 a then (T', G') else let ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k in if fst ew = 0 then (T', G') else let u' = u @ snd ew; v' = a @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic) = distribute_extension M1 (fst (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic
[PROOF STEP]
unfolding ew[symmetric] Let_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (if after_initial M1 u = after_initial M1 a then (T', G') else if fst ew = 0 then (T', G') else distribute_extension M1 (fst (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic) = distribute_extension M1 (fst (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic
[PROOF STEP]
using ew False \<open>after_initial M1 u \<noteq> after_initial M1 a\<close>
[PROOF STATE]
proof (prove)
using this:
ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k
fst ew \<noteq> 0
after_initial M1 u \<noteq> after_initial M1 a

goal (1 subgoal):
 1. (if after_initial M1 u = after_initial M1 a then (T', G') else if fst ew = 0 then (T', G') else distribute_extension M1 (fst (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic) = distribute_extension M1 (fst (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) (snd (distribute_extension M1 T' G' cg_lookup cg_insert u (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic)) cg_lookup cg_insert a (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew))) completeInputTraces append_heuristic
[PROOF STEP]
by meson
[PROOF STATE]
proof (state)
this:
dh (T', G') a = distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "L M1 \<inter> set (fst (dh (T',G') a)) = L M2 \<inter> set (fst (dh (T',G') a))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))
[PROOF STEP]
using snoc.prems(3)
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))
[PROOF STEP]
using \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a\<close> \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')

goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) \<subseteq> set (fst (dh (T',G') a))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (dh (T', G') a))
[PROOF STEP]
by (metis TG' \<open>dh (T', G') a = distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic\<close> distribute_extension_subset)
[PROOF STATE]
proof (state)
this:
Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (dh (T', G') a))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))
Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (dh (T', G') a))
[PROOF STEP]
have "(L M1 \<inter> set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) = L M2 \<inter> set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)))"
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))
Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) \<subseteq> Prefix_Tree.set (fst (dh (T', G') a))

goal (1 subgoal):
 1. L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
obtain u' where "converge M1 u u'" and "converge M2 u u'"
                      and "u' @ w' \<in> set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))"
                      and "convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>u'. \<lbrakk>converge M1 u u'; converge M2 u u'; u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)); convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using distribute_extension_adds_sequence[OF assms(1,3) \<open>u \<in> L M1\<close> \<open>u \<in> L M2\<close> \<open>convergence_graph_lookup_invar M1 M2 cg_lookup G'\<close> \<open>convergence_graph_insert_invar M1 M2 cg_lookup cg_insert\<close>, of _ _ completeInputTraces append_heuristic, OF _ assms(13) ]
                  \<open>(L M1 \<inter> set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) = L M2 \<inter> set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)))\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) \<Longrightarrow> \<exists>u'. converge M1 u u' \<and> u' @ ?w \<in> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) \<and> converge M2 u u'
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) \<Longrightarrow> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic))
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<And>u'. \<lbrakk>converge M1 u u'; converge M2 u u'; u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)); convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
unfolding TG'
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) \<Longrightarrow> \<exists>u'. converge M1 u u' \<and> u' @ ?w \<in> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) \<and> converge M2 u u'
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic)) \<Longrightarrow> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (distribute_extension M1 ?T G' cg_lookup cg_insert u ?w completeInputTraces append_heuristic))
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<And>u'. \<lbrakk>converge M1 u u'; converge M2 u u'; u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic)); convergence_graph_lookup_invar M1 M2 cg_lookup (snd (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
converge M1 u u'
converge M2 u u'
u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))
convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
converge M1 u u'
converge M2 u u'
u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))
convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')
[PROOF STEP]
have "u' @ w' \<in> set (fst (dh (T',G') a))"
[PROOF STATE]
proof (prove)
using this:
converge M1 u u'
converge M2 u u'
u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))
convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')

goal (1 subgoal):
 1. u' @ w' \<in> Prefix_Tree.set (fst (dh (T', G') a))
[PROOF STEP]
unfolding \<open>dh (T',G') a = distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic\<close>
[PROOF STATE]
proof (prove)
using this:
converge M1 u u'
converge M2 u u'
u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic))
convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')

goal (1 subgoal):
 1. u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic))
[PROOF STEP]
by (metis (no_types, opaque_lifting) TG' distribute_extension_subset in_mono)
[PROOF STATE]
proof (state)
this:
u' @ w' \<in> Prefix_Tree.set (fst (dh (T', G') a))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
obtain a' where "converge M1 a a'" and "converge M2 a a'"
                      and "a' @ w' \<in> set (fst (dh (T',G') a))"
                      and "convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T',G') a))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>a'. \<lbrakk>converge M1 a a'; converge M2 a a'; a' @ w' \<in> Prefix_Tree.set (fst (dh (T', G') a)); convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T', G') a))\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using distribute_extension_adds_sequence[OF assms(1,3) \<open>a \<in> L M1\<close> \<open>a \<in> L M2\<close> \<open>convergence_graph_lookup_invar M1 M2 cg_lookup (snd TG')\<close> \<open>convergence_graph_insert_invar M1 M2 cg_lookup cg_insert\<close>, of "fst TG'" w' completeInputTraces append_heuristic, OF _ assms(13)]
                  \<open>L M1 \<inter> set (fst (dh (T',G') a)) = L M2 \<inter> set (fst (dh (T',G') a))\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) \<Longrightarrow> \<exists>u'. converge M1 a u' \<and> u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) \<and> converge M2 a u'
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) \<Longrightarrow> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic))
L M1 \<inter> Prefix_Tree.set (fst (dh (T', G') a)) = L M2 \<inter> Prefix_Tree.set (fst (dh (T', G') a))

goal (1 subgoal):
 1. (\<And>a'. \<lbrakk>converge M1 a a'; converge M2 a a'; a' @ w' \<in> Prefix_Tree.set (fst (dh (T', G') a)); convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T', G') a))\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
unfolding \<open>dh (T',G') a = distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic\<close>
[PROOF STATE]
proof (prove)
using this:
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) \<Longrightarrow> \<exists>u'. converge M1 a u' \<and> u' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) \<and> converge M2 a u'
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) \<Longrightarrow> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic))
L M1 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<And>a'. \<lbrakk>converge M1 a a'; converge M2 a a'; a' @ w' \<in> Prefix_Tree.set (fst (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic)); convergence_graph_lookup_invar M1 M2 cg_lookup (snd (distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
converge M1 a a'
converge M2 a a'
a' @ w' \<in> Prefix_Tree.set (fst (dh (T', G') a))
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T', G') a))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "u' \<in> L M1" and "a' \<in> L M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. u' \<in> L M1 &&& a' \<in> L M1
[PROOF STEP]
using \<open>converge M1 u u'\<close> \<open>converge M1 a a'\<close>
[PROOF STATE]
proof (prove)
using this:
converge M1 u u'
converge M1 a a'

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

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "?P2 (X@[a])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using \<open>convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T',G') a))\<close>
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T', G') a))

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using False \<open>after_initial M1 u \<noteq> after_initial M1 a\<close>
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T', G') a))
fst ew \<noteq> 0
after_initial M1 u \<noteq> after_initial M1 a

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a\<close> \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic= (T', G')\<close>
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (dh (T', G') a))
fst ew \<noteq> 0
after_initial M1 u \<noteq> after_initial M1 a
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a
spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by presburger
[PROOF STATE]
proof (state)
this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
proof (cases "does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)

goal (2 subgoals):
 1. does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
[PROOF STEP]
have "distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'"
[PROOF STATE]
proof (prove)
using this:
does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'
[PROOF STEP]
using does_distinguish_correctness[OF assms(1) after_is_state[OF assms(1) \<open>u \<in> L M1\<close>] after_is_state[OF assms(1) \<open>a \<in> L M1\<close>]] w'
[PROOF STATE]
proof (prove)
using this:
does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
does_distinguish M1 (after_initial M1 u) (after_initial M1 a) ?io = distinguishes M1 (after_initial M1 u) (after_initial M1 a) ?io
w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ w)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'

goal (2 subgoals):
 1. does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
 2. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using distinguish_converge_diverge[OF assms(1,2,3) \<open>u' \<in> L M1\<close> \<open>a' \<in> L M1\<close> \<open>converge M1 u u'\<close> \<open>converge M1 a a'\<close> \<open>converge M2 u u'\<close> \<open>converge M2 a a'\<close> \<open>distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'\<close> \<open>u' @ w' \<in> set (fst (dh (T',G') a))\<close> \<open>a' @ w' \<in> set (fst (dh (T',G') a))\<close> \<open>L M1 \<inter> set (fst (dh (T',G') a)) = L M2 \<inter> set (fst (dh (T',G') a))\<close>]
                    \<open>?P2 (X@[a])\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u a
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
[PROOF STEP]
have "\<not> distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew)"
[PROOF STATE]
proof (prove)
using this:
\<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)

goal (1 subgoal):
 1. \<not> distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
[PROOF STEP]
using does_distinguish_correctness[OF assms(1) after_is_state[OF assms(1) \<open>u \<in> L M1\<close>] after_is_state[OF assms(1) \<open>a \<in> L M1\<close>]]
[PROOF STATE]
proof (prove)
using this:
\<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
does_distinguish M1 (after_initial M1 u) (after_initial M1 a) ?io = distinguishes M1 (after_initial M1 u) (after_initial M1 a) ?io

goal (1 subgoal):
 1. \<not> distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<not> distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew)

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
[PROOF STEP]
have "snd ew \<in> LS M1 (after_initial M1 u) = (snd ew \<in> LS M1 (after_initial M1 a))"
[PROOF STATE]
proof (prove)
using this:
\<not> distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew)

goal (1 subgoal):
 1. (snd ew \<in> LS M1 (after_initial M1 u)) = (snd ew \<in> LS M1 (after_initial M1 a))
[PROOF STEP]
unfolding distinguishes_def
[PROOF STATE]
proof (prove)
using this:
\<not> (snd ew \<in> LS M1 (after_initial M1 u) \<union> LS M1 (after_initial M1 a) \<and> snd ew \<notin> LS M1 (after_initial M1 u) \<inter> LS M1 (after_initial M1 a))

goal (1 subgoal):
 1. (snd ew \<in> LS M1 (after_initial M1 u)) = (snd ew \<in> LS M1 (after_initial M1 a))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
(snd ew \<in> LS M1 (after_initial M1 u)) = (snd ew \<in> LS M1 (after_initial M1 a))

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
(snd ew \<in> LS M1 (after_initial M1 u)) = (snd ew \<in> LS M1 (after_initial M1 a))

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "snd ew \<in> LS M1 (after_initial M1 u) \<or> (snd ew \<in> LS M1 (after_initial M1 a))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)
[PROOF STEP]
using \<open>distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)\<close>
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)

goal (1 subgoal):
 1. snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)
[PROOF STEP]
using language_prefix[of "snd ew" \<gamma>]
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)
snd ew @ \<gamma> \<in> LS ?M ?q \<Longrightarrow> snd ew \<in> LS ?M ?q

goal (1 subgoal):
 1. snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)
[PROOF STEP]
unfolding distinguishes_def
[PROOF STATE]
proof (prove)
using this:
snd ew @ \<gamma> \<in> LS M1 (after_initial M1 u) \<union> LS M1 (after_initial M1 a) \<and> snd ew @ \<gamma> \<notin> LS M1 (after_initial M1 u) \<inter> LS M1 (after_initial M1 a)
snd ew @ \<gamma> \<in> LS ?M ?q \<Longrightarrow> snd ew \<in> LS ?M ?q

goal (1 subgoal):
 1. snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)
[PROOF STEP]
by fast
[PROOF STATE]
proof (state)
this:
snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
(snd ew \<in> LS M1 (after_initial M1 u)) = (snd ew \<in> LS M1 (after_initial M1 a))
snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)
[PROOF STEP]
have "snd ew \<in> LS M1 (after_initial M1 u)" and "snd ew \<in> LS M1 (after_initial M1 a)"
[PROOF STATE]
proof (prove)
using this:
(snd ew \<in> LS M1 (after_initial M1 u)) = (snd ew \<in> LS M1 (after_initial M1 a))
snd ew \<in> LS M1 (after_initial M1 u) \<or> snd ew \<in> LS M1 (after_initial M1 a)

goal (1 subgoal):
 1. snd ew \<in> LS M1 (after_initial M1 u) &&& snd ew \<in> LS M1 (after_initial M1 a)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
snd ew \<in> LS M1 (after_initial M1 u)
snd ew \<in> LS M1 (after_initial M1 a)

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "after_initial M1 (u @ snd ew) \<in> states M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 (u @ snd ew) \<in> FSM.states M1
[PROOF STEP]
using \<open>snd ew \<in> LS M1 (after_initial M1 u)\<close> after_is_state[OF assms(1) \<open>u \<in> L M1\<close>]
[PROOF STATE]
proof (prove)
using this:
snd ew \<in> LS M1 (after_initial M1 u)
after_initial M1 u \<in> FSM.states M1

goal (1 subgoal):
 1. after_initial M1 (u @ snd ew) \<in> FSM.states M1
[PROOF STEP]
by (meson after_is_state after_language_iff assms(1) assms(5))
[PROOF STATE]
proof (state)
this:
after_initial M1 (u @ snd ew) \<in> FSM.states M1

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
after_initial M1 (u @ snd ew) \<in> FSM.states M1

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "after_initial M1 (a @ snd ew) \<in> states M1"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 (a @ snd ew) \<in> FSM.states M1
[PROOF STEP]
using \<open>snd ew \<in> LS M1 (after_initial M1 a)\<close> after_is_state[OF assms(1) \<open>a \<in> L M1\<close>]
[PROOF STATE]
proof (prove)
using this:
snd ew \<in> LS M1 (after_initial M1 a)
after_initial M1 a \<in> FSM.states M1

goal (1 subgoal):
 1. after_initial M1 (a @ snd ew) \<in> FSM.states M1
[PROOF STEP]
by (meson \<open>a \<in> L M1\<close> after_is_state after_language_iff assms(1))
[PROOF STATE]
proof (state)
this:
after_initial M1 (a @ snd ew) \<in> FSM.states M1

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
after_initial M1 (a @ snd ew) \<in> FSM.states M1

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)
[PROOF STEP]
using \<open>distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)\<close>
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 u) (after_initial M1 a) (snd ew @ \<gamma>)

goal (1 subgoal):
 1. after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)
[PROOF STEP]
by (metis \<open>a \<in> L M1\<close> \<open>snd ew \<in> LS M1 (after_initial M1 a)\<close> \<open>snd ew \<in> LS M1 (after_initial M1 u)\<close> after_distinguishes_language after_language_iff append.assoc assms(1) assms(5))
[PROOF STATE]
proof (state)
this:
after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
after_initial M1 (u @ snd ew) \<in> FSM.states M1
after_initial M1 (a @ snd ew) \<in> FSM.states M1
after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)
[PROOF STEP]
have "distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w"
[PROOF STATE]
proof (prove)
using this:
after_initial M1 (u @ snd ew) \<in> FSM.states M1
after_initial M1 (a @ snd ew) \<in> FSM.states M1
after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w
[PROOF STEP]
unfolding w
[PROOF STATE]
proof (prove)
using this:
after_initial M1 (u @ snd ew) \<in> FSM.states M1
after_initial M1 (a @ snd ew) \<in> FSM.states M1
after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) (get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)))
[PROOF STEP]
using assms(7)
[PROOF STATE]
proof (prove)
using this:
after_initial M1 (u @ snd ew) \<in> FSM.states M1
after_initial M1 (a @ snd ew) \<in> FSM.states M1
after_initial M1 (u @ snd ew) \<noteq> after_initial M1 (a @ snd ew)
\<lbrakk>?q1.0 \<in> FSM.states M1; ?q2.0 \<in> FSM.states M1; ?q1.0 \<noteq> ?q2.0\<rbrakk> \<Longrightarrow> distinguishes M1 ?q1.0 ?q2.0 (get_distinguishing_trace ?q1.0 ?q2.0)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) (get_distinguishing_trace (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "w' = snd ew @ w"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. w' = snd ew @ w
[PROOF STEP]
using False w'
[PROOF STATE]
proof (prove)
using this:
\<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew)
w' = (if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ w)

goal (1 subgoal):
 1. w' = snd ew @ w
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
w' = snd ew @ w

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w
w' = snd ew @ w
[PROOF STEP]
have "distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'"
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w
w' = snd ew @ w

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'
[PROOF STEP]
using distinguish_prepend_initial[OF assms(1)]
[PROOF STATE]
proof (prove)
using this:
distinguishes M1 (after_initial M1 (u @ snd ew)) (after_initial M1 (a @ snd ew)) w
w' = snd ew @ w
\<lbrakk>distinguishes M1 (after_initial M1 (?io1.0 @ ?io)) (after_initial M1 (?io2.0 @ ?io)) ?w; ?io1.0 @ ?io \<in> L M1; ?io2.0 @ ?io \<in> L M1\<rbrakk> \<Longrightarrow> distinguishes M1 (after_initial M1 ?io1.0) (after_initial M1 ?io2.0) (?io @ ?w)

goal (1 subgoal):
 1. distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'
[PROOF STEP]
by (meson \<open>a \<in> L M1\<close> \<open>snd ew \<in> LS M1 (after_initial M1 a)\<close> \<open>snd ew \<in> LS M1 (after_initial M1 u)\<close> after_language_iff assms(1) assms(5))
[PROOF STATE]
proof (state)
this:
distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'

goal (1 subgoal):
 1. \<not> does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using distinguish_converge_diverge[OF assms(1,2,3) \<open>u' \<in> L M1\<close> \<open>a' \<in> L M1\<close> \<open>converge M1 u u'\<close> \<open>converge M1 a a'\<close> \<open>converge M2 u u'\<close> \<open>converge M2 a a'\<close> \<open>distinguishes M1 (after_initial M1 u) (after_initial M1 a) w'\<close> \<open>u' @ w' \<in> set (fst (dh (T',G') a))\<close> \<open>a' @ w' \<in> set (fst (dh (T',G') a))\<close> \<open>L M1 \<inter> set (fst (dh (T',G') a)) = L M2 \<inter> set (fst (dh (T',G') a))\<close>]
                    \<open>?P2 (X@[a])\<close>
[PROOF STATE]
proof (prove)
using this:
\<not> converge M2 u a
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
case False
[PROOF STATE]
proof (state)
this:
\<not> \<not> converge M1 u a

goal (1 subgoal):
 1. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> \<not> converge M1 u a
[PROOF STEP]
have "after_initial M1 u = after_initial M1 a"
[PROOF STATE]
proof (prove)
using this:
\<not> \<not> converge M1 u a

goal (1 subgoal):
 1. after_initial M1 u = after_initial M1 a
[PROOF STEP]
by (meson \<open>a \<in> L M1\<close> assms(1) assms(3) assms(5) convergence_minimal)
[PROOF STATE]
proof (state)
this:
after_initial M1 u = after_initial M1 a

goal (1 subgoal):
 1. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
after_initial M1 u = after_initial M1 a
[PROOF STEP]
have "dh (T',G') a = (T',G')"
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u = after_initial M1 a

goal (1 subgoal):
 1. dh (T', G') a = (T', G')
[PROOF STEP]
unfolding dh case_prod_conv
[PROOF STATE]
proof (prove)
using this:
after_initial M1 u = after_initial M1 a

goal (1 subgoal):
 1. (if after_initial M1 u = after_initial M1 a then (T', G') else let ew = get_prefix_of_separating_sequence M1 T' G' cg_lookup get_distinguishing_trace u a k in if fst ew = 0 then (T', G') else let u' = u @ snd ew; v' = a @ snd ew; w' = if does_distinguish M1 (after_initial M1 u) (after_initial M1 a) (snd ew) then snd ew else snd ew @ get_distinguishing_trace (after_initial M1 u') (after_initial M1 v'); TG' = distribute_extension M1 T' G' cg_lookup cg_insert u w' completeInputTraces append_heuristic in distribute_extension M1 (fst TG') (snd TG') cg_lookup cg_insert a w' completeInputTraces append_heuristic) = (T', G')
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
dh (T', G') a = (T', G')

goal (1 subgoal):
 1. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
dh (T', G') a = (T', G')
[PROOF STEP]
have "?P2 (X@[a])"
[PROOF STATE]
proof (prove)
using this:
dh (T', G') a = (T', G')

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using \<open>?P2 X\<close>
[PROOF STATE]
proof (prove)
using this:
dh (T', G') a = (T', G')
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by (metis \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X@[a]) k completeInputTraces append_heuristic = dh (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic) a\<close> \<open>spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic = (T', G')\<close>)
[PROOF STATE]
proof (state)
this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<not> \<not> converge M1 u a \<Longrightarrow> (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using False
[PROOF STATE]
proof (prove)
using this:
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
\<not> \<not> converge M1 u a

goal (1 subgoal):
 1. (\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (2 subgoals):
 1. \<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
show "\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a"
            and "?P2 (X@[a])"
[PROOF STATE]
proof (prove)
using this:
(\<not> converge M1 u a \<longrightarrow> \<not> converge M2 u a) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a) &&& convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by blast+
[PROOF STATE]
proof (state)
this:
\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
have "?P1 (X@[a])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
[PROOF STEP]
have "\<And> v . v \<in> list.set X \<Longrightarrow> \<not>converge M1 u v \<Longrightarrow> \<not>converge M2 u v"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<And>v. \<lbrakk>v \<in> list.set X; \<not> converge M1 u v\<rbrakk> \<Longrightarrow> \<not> converge M2 u v
[PROOF STEP]
using \<open>?P1 X\<close>
[PROOF STATE]
proof (prove)
using this:
\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v

goal (1 subgoal):
 1. \<And>v. \<lbrakk>v \<in> list.set X; \<not> converge M1 u v\<rbrakk> \<Longrightarrow> \<not> converge M2 u v
[PROOF STEP]
unfolding preserves_divergence.simps
[PROOF STATE]
proof (prove)
using this:
\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v

goal (1 subgoal):
 1. \<And>v. \<lbrakk>v \<in> list.set X; \<not> converge M1 u v\<rbrakk> \<Longrightarrow> \<not> converge M2 u v
[PROOF STEP]
using Int_absorb2 \<open>list.set X \<subseteq> L M1\<close> assms(5)
[PROOF STATE]
proof (prove)
using this:
\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
?A \<subseteq> ?B \<Longrightarrow> ?A \<inter> ?B = ?A
list.set X \<subseteq> L M1
u \<in> L M1

goal (1 subgoal):
 1. \<And>v. \<lbrakk>v \<in> list.set X; \<not> converge M1 u v\<rbrakk> \<Longrightarrow> \<not> converge M2 u v
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<lbrakk>?v \<in> list.set X; \<not> converge M1 u ?v\<rbrakk> \<Longrightarrow> \<not> converge M2 u ?v

goal (1 subgoal):
 1. \<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<lbrakk>?v \<in> list.set X; \<not> converge M1 u ?v\<rbrakk> \<Longrightarrow> \<not> converge M2 u ?v
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>?v \<in> list.set X; \<not> converge M1 u ?v\<rbrakk> \<Longrightarrow> \<not> converge M2 u ?v

goal (1 subgoal):
 1. \<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
[PROOF STEP]
using \<open>\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a\<close>
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>?v \<in> list.set X; \<not> converge M1 u ?v\<rbrakk> \<Longrightarrow> \<not> converge M2 u ?v
\<not> converge M1 u a \<Longrightarrow> \<not> converge M2 u a

goal (1 subgoal):
 1. \<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v

goal (1 subgoal):
 1. \<And>x xs. \<lbrakk>\<lbrakk>list.set xs \<subseteq> L M1; list.set xs \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set xs \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u xs k completeInputTraces append_heuristic)); list.set (xs @ [x]) \<subseteq> L M1; list.set (xs @ [x]) \<subseteq> L M2; L M1 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic)) = L M2 \<inter> Prefix_Tree.set (fst (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))\<rbrakk> \<Longrightarrow> (\<forall>v. v \<in> list.set (xs @ [x]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (xs @ [x]) k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
using this:
\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v

goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
using \<open>?P2 (X@[a])\<close>
[PROOF STATE]
proof (prove)
using this:
\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. (\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(\<forall>v. v \<in> list.set (X @ [a]) \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u (X @ [a]) k completeInputTraces append_heuristic))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (2 subgoals):
 1. \<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
 2. convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
(\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
show "?P1 X" and "?P2 X"
[PROOF STATE]
proof (prove)
using this:
(\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v) \<and> convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal (1 subgoal):
 1. \<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v &&& convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
\<forall>v. v \<in> list.set X \<longrightarrow> \<not> converge M1 u v \<longrightarrow> \<not> converge M2 u v
convergence_graph_lookup_invar M1 M2 cg_lookup (snd (spyh_distinguish M1 T G cg_lookup cg_insert get_distinguishing_trace u X k completeInputTraces append_heuristic))

goal:
No subgoals!
[PROOF STEP]
qed