This GitLab instance reached the end of its service life. It won't be possible to create new users or projects.

Please read the deprecation notice for more information concerning the deprecation timeline

Visit migration.git.tu-berlin.de (internal network only) to import your old projects to the new GitLab platform 📥

Commit 3a99aa3e by benkeks

Improve Isabelle proofs

parent a6d32189
...@@ -12,74 +12,74 @@ context lts_tau ...@@ -12,74 +12,74 @@ context lts_tau
begin begin
definition fp_step :: definition fp_step ::
"'s rel \<Rightarrow> 's rel" \<open>'s rel \<Rightarrow> 's rel\<close>
where where
"fp_step R1 \<equiv> { (p,q)\<in>R1. \<open>fp_step R1 \<equiv> { (p,q)\<in>R1.
(\<forall> p' a. p \<longmapsto> a p' \<longrightarrow> (\<forall> p' a. p \<longmapsto>a p' \<longrightarrow>
(\<exists> q'. ((p',q')\<in>R1) \<and> (q \<longmapsto>^ a q'))) (\<exists> q'. ((p',q')\<in>R1) \<and> (q \<Rightarrow>^a q')))
\<and> (\<exists> q'. q \<longmapsto>*tau q' \<and> ((q',p)\<in>R1)) }" \<and> (\<exists> q'. q \<longmapsto>*tau q' \<and> ((q',p)\<in>R1)) }\<close>
lemma mono_fp_step: lemma mono_fp_step:
"mono fp_step" \<open>mono fp_step\<close>
proof (rule, safe) proof (rule, safe)
fix x y::"'s rel" and p q fix x y::\<open>'s rel\<close> and p q
assume assume
"x \<subseteq> y" \<open>x \<subseteq> y\<close>
"(p, q) \<in> fp_step x" \<open>(p, q) \<in> fp_step x\<close>
thus "(p, q) \<in> fp_step y" thus \<open>(p, q) \<in> fp_step y\<close>
unfolding fp_step_def unfolding fp_step_def
by (auto, blast) by (auto, blast)
qed qed
lemma fp_fp_step: lemma fp_fp_step:
assumes assumes
"R = fp_step R" \<open>R = fp_step R\<close>
shows shows
"coupled_simulation (\<lambda> p q. (p, q) \<in> R)" \<open>coupled_simulation (\<lambda> p q. (p, q) \<in> R)\<close>
using assms unfolding fp_step_def coupled_simulation_def using assms unfolding fp_step_def coupled_simulation_def
by fastforce by fastforce
lemma gfp_fp_step_subset_gcs: lemma gfp_fp_step_subset_gcs:
shows "(gfp fp_step) \<subseteq> { (p,q) . greatest_coupled_simulation p q }" shows \<open>(gfp fp_step) \<subseteq> { (p,q) . greatest_coupled_simulation p q }\<close>
unfolding gcs_eq_coupled_sim_by[symmetric] unfolding gcs_eq_coupled_sim_by[symmetric]
proof clarify proof clarify
fix a b fix a b
assume assume
"(a, b) \<in> gfp fp_step" \<open>(a, b) \<in> gfp fp_step\<close>
thus "a \<sqsubseteq>cs b" thus \<open>a \<sqsubseteq>cs b\<close>
using fp_fp_step mono_fp_step gfp_unfold by auto using fp_fp_step mono_fp_step gfp_unfold by auto
qed qed
lemma fp_fp_step_gcs: lemma fp_fp_step_gcs:
assumes assumes
"R = { (p,q) . greatest_coupled_simulation p q }" \<open>R = { (p,q) . greatest_coupled_simulation p q }\<close>
shows shows
"fp_step R = R" \<open>fp_step R = R\<close>
unfolding assms unfolding assms
proof safe proof safe
fix p q fix p q
assume assume
"(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}" \<open>(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}\<close>
hence "(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<longmapsto>^ a q')) \<and> hence \<open>(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<Rightarrow>^a q')) \<and>
(\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)" (\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)\<close>
unfolding fp_step_def by auto unfolding fp_step_def by auto
hence "(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<longmapsto>^^ a q')) \<and> hence \<open>(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<Rightarrow>^^ a q')) \<and>
(\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)" using weak_step_tau2_def by simp (\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)\<close> using weak_step_tau2_def by simp
thus "greatest_coupled_simulation p q" thus \<open>greatest_coupled_simulation p q\<close>
using lts_tau.gcs by metis using lts_tau.gcs by metis
next next
fix p q fix p q
assume assume
"greatest_coupled_simulation p q" \<open>greatest_coupled_simulation p q\<close>
hence "(p, q) \<in> {(x, y). greatest_coupled_simulation x y} \<and> (\<forall> p' a. p \<longmapsto> a p' \<longrightarrow> hence \<open>(p, q) \<in> {(x, y). greatest_coupled_simulation x y} \<and> (\<forall> p' a. p \<longmapsto>a p' \<longrightarrow>
(\<exists> q'. (greatest_coupled_simulation p' q') \<and> (q \<longmapsto>^ a q'))) (\<exists> q'. (greatest_coupled_simulation p' q') \<and> (q \<Rightarrow>^a q')))
\<and> (\<exists> q'. q \<longmapsto>*tau q' \<and> (greatest_coupled_simulation q' p))" \<and> (\<exists> q'. q \<longmapsto>*tau q' \<and> (greatest_coupled_simulation q' p))\<close>
using gcs_is_coupled_simulation unfolding coupled_simulation_def by blast using gcs_is_coupled_simulation unfolding coupled_simulation_def by blast
thus "(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}" thus \<open>(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}\<close>
unfolding fp_step_def by blast unfolding fp_step_def by blast
qed qed
lemma gfp_fp_step_gcs: "gfp fp_step = { (p,q) . greatest_coupled_simulation p q }" lemma gfp_fp_step_gcs: \<open>gfp fp_step = { (p,q) . greatest_coupled_simulation p q }\<close>
using fp_fp_step_gcs gfp_fp_step_subset_gcs using fp_fp_step_gcs gfp_fp_step_subset_gcs
by (simp add: equalityI gfp_upperbound) by (simp add: equalityI gfp_upperbound)
...@@ -89,11 +89,11 @@ context lts_tau_finite ...@@ -89,11 +89,11 @@ context lts_tau_finite
begin begin
lemma gfp_fp_step_while: lemma gfp_fp_step_while:
shows shows
"gfp fp_step = while (\<lambda>R. fp_step R \<noteq> R) fp_step top" \<open>gfp fp_step = while (\<lambda>R. fp_step R \<noteq> R) fp_step top\<close>
using gfp_while_lattice[OF mono_fp_step] finite_state_rel Finite_Set.finite_set by blast using gfp_while_lattice[OF mono_fp_step] finite_state_rel Finite_Set.finite_set by blast
theorem coupled_sim_fp_step_while: theorem coupled_sim_fp_step_while:
shows "while (\<lambda>R. fp_step R \<noteq> R) fp_step top = { (p,q) . greatest_coupled_simulation p q }" shows \<open>while (\<lambda>R. fp_step R \<noteq> R) fp_step top = { (p,q) . greatest_coupled_simulation p q }\<close>
using gfp_fp_step_while gfp_fp_step_gcs by blast using gfp_fp_step_while gfp_fp_step_gcs by blast
end end
......
section \<open>Fixed Point Algorithm for Coupled Similarity\<close> section \<open>Fixed Point Algorithm for Coupled Similarity\<close>
subsection \<open>The Algorithm\<close>
theory CS_Fixpoint_Algo_Delay theory CS_Fixpoint_Algo_Delay
imports imports
Coupled_Simulation Coupled_Simulation
Finite_Weak_Transition_Systems
"~~/src/HOL/Library/While_Combinator" "~~/src/HOL/Library/While_Combinator"
"~~/src/HOL/Library/Finite_Lattice" "~~/src/HOL/Library/Finite_Lattice"
begin begin
...@@ -12,83 +14,99 @@ context lts_tau ...@@ -12,83 +14,99 @@ context lts_tau
begin begin
definition fp_step :: definition fp_step ::
"'s rel \<Rightarrow> 's rel" \<open>'s rel \<Rightarrow> 's rel\<close>
where where
"fp_step R1 \<equiv> { (p,q)\<in>R1. \<open>fp_step R1 \<equiv> { (p,q)\<in>R1.
(\<forall> p' a. p \<longmapsto> a p' \<longrightarrow> (\<forall> p' a. p \<longmapsto>a p' \<longrightarrow>
(\<exists> q'. ((p',q')\<in>R1) \<and> (q \<longmapsto>^~ a q'))) (tau a \<longrightarrow> (p',q)\<in>R1) \<and>
\<and> (\<exists> q'. q \<longmapsto>*tau q' \<and> ((q',p)\<in>R1)) }" (\<not>tau a \<longrightarrow> (\<exists> q'. ((p',q')\<in>R1) \<and> (q =\<rhd>a q')))) \<and>
(\<exists> q'. q \<longmapsto>*tau q' \<and> ((q',p)\<in>R1)) }\<close>
definition fp_compute_cs :: \<open>'s rel\<close>
where \<open>fp_compute_cs \<equiv> while (\<lambda>R. fp_step R \<noteq> R) fp_step top\<close>
subsection \<open>Correctness\<close>
lemma mono_fp_step: lemma mono_fp_step:
"mono fp_step" \<open>mono fp_step\<close>
proof (rule, safe) proof (rule, safe)
fix x y::"'s rel" and p q fix x y::\<open>'s rel\<close> and p q
assume assume
"x \<subseteq> y" \<open>x \<subseteq> y\<close>
"(p, q) \<in> fp_step x" \<open>(p, q) \<in> fp_step x\<close>
thus "(p, q) \<in> fp_step y" thus \<open>(p, q) \<in> fp_step y\<close>
unfolding fp_step_def unfolding fp_step_def
by (auto, blast) by (auto, blast)
qed qed
thm prod.simps(2)
lemma fp_fp_step: lemma fp_fp_step:
assumes assumes
"R = fp_step R" \<open>R = fp_step R\<close>
shows shows
"coupled_delay_simulation (\<lambda> p q. (p, q) \<in> R)" \<open>coupled_delay_simulation (\<lambda> p q. (p, q) \<in> R)\<close>
using assms unfolding fp_step_def coupled_delay_simulation_def delay_simulation_def using assms unfolding fp_step_def coupled_delay_simulation_def delay_simulation_def
by fastforce by (auto, blast, fastforce+)
lemma gfp_fp_step_subset_gcs: lemma gfp_fp_step_subset_gcs:
shows "(gfp fp_step) \<subseteq> { (p,q) . greatest_coupled_simulation p q }" shows \<open>(gfp fp_step) \<subseteq> { (p,q) . greatest_coupled_simulation p q }\<close>
unfolding gcs_eq_coupled_sim_by[symmetric] unfolding gcs_eq_coupled_sim_by[symmetric]
proof clarify proof clarify
fix a b fix a b
assume assume
"(a, b) \<in> gfp fp_step" \<open>(a, b) \<in> gfp fp_step\<close>
thus "a \<sqsubseteq>cs b" thus \<open>a \<sqsubseteq>cs b\<close>
unfolding coupled_sim_by_eq_delay_coupled_simulation unfolding coupled_sim_by_eq_coupled_delay_simulation
using fp_fp_step mono_fp_step gfp_unfold using fp_fp_step mono_fp_step gfp_unfold
by metis by metis
qed qed
lemma fp_fp_step_gcs: lemma fp_fp_step_gcs:
assumes assumes
"R = { (p,q) . greatest_coupled_simulation p q }" \<open>R = { (p,q) . greatest_coupled_simulation p q }\<close>
shows shows
"fp_step R = R" \<open>fp_step R = R\<close>
unfolding assms unfolding assms
proof safe proof safe
fix p q fix p q
assume assume
"(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}" \<open>(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}\<close>
hence "(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<longmapsto>^~ a q')) \<and> hence
(\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)" \<open>(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow>
(tau a \<longrightarrow> greatest_coupled_simulation p' q) \<and>
(\<not>tau a \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q =\<rhd>a q'))) \<and>
(\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)\<close>
unfolding fp_step_def by auto unfolding fp_step_def by auto
hence "(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<longmapsto>^ a q')) \<and> hence \<open>(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<Rightarrow>^a q')) \<and>
(\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)" (\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)\<close>
unfolding fp_step_def using weak_step_delay_implies_weak_tau by blast unfolding fp_step_def using weak_step_delay_implies_weak_tau steps.refl by blast
hence "(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<longmapsto>^^ a q')) \<and> hence \<open>(\<forall>p' a. p \<longmapsto>a p' \<longrightarrow> (\<exists>q'. greatest_coupled_simulation p' q' \<and> q \<Rightarrow>^^a q')) \<and>
(\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)" using weak_step_tau2_def by simp (\<exists>q'. q \<longmapsto>* tau q' \<and> greatest_coupled_simulation q' p)\<close>
thus "greatest_coupled_simulation p q" using weak_step_tau2_def by simp
thus \<open>greatest_coupled_simulation p q\<close>
using lts_tau.gcs by metis using lts_tau.gcs by metis
next next
fix p q fix p q
assume asm: assume asm:
"greatest_coupled_simulation p q" \<open>greatest_coupled_simulation p q\<close>
then have "(p, q) \<in> {(x, y). greatest_coupled_simulation x y}" by blast then have \<open>(p, q) \<in> {(x, y). greatest_coupled_simulation x y}\<close> by blast
moreover from asm have \<open>\<exists> R. R p q \<and> coupled_delay_simulation R\<close> moreover from asm have \<open>\<exists> R. R p q \<and> coupled_delay_simulation R\<close>
unfolding gcs_eq_coupled_sim_by[symmetric] coupled_sim_by_eq_delay_coupled_simulation . unfolding gcs_eq_coupled_sim_by[symmetric] coupled_sim_by_eq_coupled_delay_simulation .
moreover from asm have "(\<forall> p' a. p \<longmapsto> a p' \<longrightarrow> (\<exists> q'. (greatest_coupled_simulation p' q') \<and> (q \<longmapsto>^~ a q')))" moreover from asm have \<open>\<forall> p' a. p \<longmapsto>a p' \<and> \<not>tau a \<longrightarrow>
unfolding gcs_eq_coupled_sim_by[symmetric] coupled_sim_by_eq_delay_coupled_simulation (\<exists> q'. (greatest_coupled_simulation p' q') \<and> (q =\<rhd>a q'))\<close>
unfolding gcs_eq_coupled_sim_by[symmetric] coupled_sim_by_eq_coupled_delay_simulation
by (metis coupled_delay_simulation_def delay_simulation_def)
moreover from asm have \<open>\<forall> p' a. p \<longmapsto>a p' \<and> tau a \<longrightarrow> greatest_coupled_simulation p' q\<close>
unfolding gcs_eq_coupled_sim_by[symmetric] coupled_sim_by_eq_coupled_delay_simulation
by (metis coupled_delay_simulation_def delay_simulation_def) by (metis coupled_delay_simulation_def delay_simulation_def)
moreover have "(\<exists> q'. q \<longmapsto>*tau q' \<and> (greatest_coupled_simulation q' p))" moreover have \<open>(\<exists> q'. q \<longmapsto>*tau q' \<and> (greatest_coupled_simulation q' p))\<close>
using asm gcs_is_coupled_simulation coupled_simulation_implies_coupling by blast using asm gcs_is_coupled_simulation coupled_simulation_implies_coupling by blast
ultimately show "(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}" ultimately show \<open>(p, q) \<in> fp_step {(x, y). greatest_coupled_simulation x y}\<close>
unfolding fp_step_def by blast unfolding fp_step_def by blast
qed qed
lemma gfp_fp_step_gcs: "gfp fp_step = { (p,q) . greatest_coupled_simulation p q }" lemma gfp_fp_step_gcs: \<open>gfp fp_step = { (p,q) . greatest_coupled_simulation p q }\<close>
using fp_fp_step_gcs gfp_fp_step_subset_gcs using fp_fp_step_gcs gfp_fp_step_subset_gcs
by (simp add: equalityI gfp_upperbound) by (simp add: equalityI gfp_upperbound)
...@@ -98,14 +116,14 @@ context lts_tau_finite ...@@ -98,14 +116,14 @@ context lts_tau_finite
begin begin
lemma gfp_fp_step_while: lemma gfp_fp_step_while:
shows shows
"gfp fp_step = while (\<lambda>R. fp_step R \<noteq> R) fp_step top" \<open>gfp fp_step = fp_compute_cs\<close>
unfolding fp_compute_cs_def
using gfp_while_lattice[OF mono_fp_step] finite_state_rel Finite_Set.finite_set by blast using gfp_while_lattice[OF mono_fp_step] finite_state_rel Finite_Set.finite_set by blast
theorem coupled_sim_fp_step_while: theorem coupled_sim_fp_step_while:
shows "while (\<lambda>R. fp_step R \<noteq> R) fp_step top = { (p,q) . greatest_coupled_simulation p q }" shows \<open>fp_compute_cs = { (p,q) . greatest_coupled_simulation p q }\<close>
using gfp_fp_step_while gfp_fp_step_gcs by blast using gfp_fp_step_while gfp_fp_step_gcs by blast
end end
end end
...@@ -14,258 +14,258 @@ datatype ('s, 'a) cs_game_node = ...@@ -14,258 +14,258 @@ datatype ('s, 'a) cs_game_node =
DefenderCouplingNode 's 's DefenderCouplingNode 's 's
fun (in lts_tau) cs_game_moves :: fun (in lts_tau) cs_game_moves ::
"('s, 'a) cs_game_node \<Rightarrow> ('s, 'a) cs_game_node \<Rightarrow> bool" where \<open>('s, 'a) cs_game_node \<Rightarrow> ('s, 'a) cs_game_node \<Rightarrow> bool\<close> where
simulation_challenge: simulation_challenge:
"cs_game_moves (AttackerNode p q) (DefenderStepNode a p1 q0) = \<open>cs_game_moves (AttackerNode p q) (DefenderStepNode a p1 q0) =
(p \<longmapsto> a p1 \<and> q = q0)" | (p \<longmapsto>a p1 \<and> q = q0)\<close> |
simulation_answer: simulation_answer:
"cs_game_moves (DefenderStepNode a p1 q0) (AttackerNode p11 q1) = \<open>cs_game_moves (DefenderStepNode a p1 q0) (AttackerNode p11 q1) =
(q0 \<longmapsto>^ a q1 \<and> p1 = p11)" | (q0 \<Rightarrow>^a q1 \<and> p1 = p11)\<close> |
coupling_challenge: coupling_challenge:
"cs_game_moves (AttackerNode p q) (DefenderCouplingNode p0 q0) = \<open>cs_game_moves (AttackerNode p q) (DefenderCouplingNode p0 q0) =
(p = p0 \<and> q = q0)" | (p = p0 \<and> q = q0)\<close> |
coupling_answer: coupling_answer:
"cs_game_moves (DefenderCouplingNode p0 q0) (AttackerNode q1 p00) = \<open>cs_game_moves (DefenderCouplingNode p0 q0) (AttackerNode q1 p00) =
(p0 = p00 \<and> q0 \<longmapsto>* tau q1)" | (p0 = p00 \<and> q0 \<longmapsto>* tau q1)\<close> |
cs_game_moves_no_step: cs_game_moves_no_step:
"cs_game_moves _ _ = False" \<open>cs_game_moves _ _ = False\<close>
fun cs_game_defender_node :: "('s, 'a) cs_game_node \<Rightarrow> bool" where fun cs_game_defender_node :: \<open>('s, 'a) cs_game_node \<Rightarrow> bool\<close> where
"cs_game_defender_node (AttackerNode _ _) = False" | \<open>cs_game_defender_node (AttackerNode _ _) = False\<close> |
"cs_game_defender_node (DefenderStepNode _ _ _) = True" | \<open>cs_game_defender_node (DefenderStepNode _ _ _) = True\<close> |
"cs_game_defender_node (DefenderCouplingNode _ _) = True" \<open>cs_game_defender_node (DefenderCouplingNode _ _) = True\<close>
locale cs_game = locale cs_game =
lts_tau trans \<tau> + lts_tau trans \<tau> +
simple_game cs_game_moves cs_game_defender_node initial simple_game cs_game_moves cs_game_defender_node initial
for for
trans :: "'s \<Rightarrow> 'a \<Rightarrow> 's \<Rightarrow> bool" and trans :: \<open>'s \<Rightarrow> 'a \<Rightarrow> 's \<Rightarrow> bool\<close> and
\<tau> :: "'a" and \<tau> :: \<open>'a\<close> and
initial :: "('s, 'a) cs_game_node" initial :: \<open>('s, 'a) cs_game_node\<close>
begin begin
subsection \<open>Coupled Simulation Implies Winning Strategy\<close> subsection \<open>Coupled Simulation Implies Winning Strategy\<close>
fun strategy_from_coupledsim :: "('s \<Rightarrow> 's \<Rightarrow> bool) \<Rightarrow> ('s, 'a) cs_game_node strategy" where fun strategy_from_coupledsim :: \<open>('s \<Rightarrow> 's \<Rightarrow> bool) \<Rightarrow> ('s, 'a) cs_game_node strategy\<close> where
"strategy_from_coupledsim R ((DefenderStepNode a p1 q0)#play) = \<open>strategy_from_coupledsim R ((DefenderStepNode a p1 q0)#play) =
(AttackerNode p1 (SOME q1 . R p1 q1 \<and> q0 \<longmapsto>^ a q1))" | (AttackerNode p1 (SOME q1 . R p1 q1 \<and> q0 \<Rightarrow>^a q1))\<close> |
"strategy_from_coupledsim R ((DefenderCouplingNode p0 q0)#play) = \<open>strategy_from_coupledsim R ((DefenderCouplingNode p0 q0)#play) =
(AttackerNode (SOME q1 . R q1 p0 \<and> q0 \<longmapsto>* tau q1) p0)" | (AttackerNode (SOME q1 . R q1 p0 \<and> q0 \<longmapsto>* tau q1) p0)\<close> |
"strategy_from_coupledsim _ _ = undefined" \<open>strategy_from_coupledsim _ _ = undefined\<close>
lemma attacker_followed_by_defender: lemma defender_preceded_by_attacker:
assumes assumes
"n0 # play \<in> plays" \<open>n0 # play \<in> plays\<close>
"cs_game_defender_node n0" \<open>cs_game_defender_node n0\<close>
"initial = AttackerNode p0 q0" \<open>initial = AttackerNode p0 q0\<close>
shows "\<exists> p q . hd play = AttackerNode p q \<and> cs_game_moves (AttackerNode p q) n0" "play \<noteq> []" shows \<open>\<exists> p q . hd play = AttackerNode p q \<and> cs_game_moves (AttackerNode p q) n0\<close> \<open>play \<noteq> []\<close>
proof - proof -
have n0_not_init: "n0 \<noteq> initial" using assms(2,3) by auto have n0_not_init: \<open>n0 \<noteq> initial\<close> using assms(2,3) by auto
hence "cs_game_moves (hd play) n0" using assms(1) hence \<open>cs_game_moves (hd play) n0\<close> using assms(1)
by (metis list.sel(1) list.sel(3) plays.cases) by (metis list.sel(1) list.sel(3) plays.cases)
thus "\<exists>p q. hd play = AttackerNode p q \<and> cs_game_moves (AttackerNode p q) n0" using assms(2) thus \<open>\<exists>p q. hd play = AttackerNode p q \<and> cs_game_moves (AttackerNode p q) n0\<close> using assms(2)
by (metis cs_game_defender_node.elims(2,3) local.cs_game_moves_no_step(1,2,3,7)) by (metis cs_game_defender_node.elims(2,3) local.cs_game_moves_no_step(1,2,3,7))
show "play \<noteq> []" using n0_not_init assms(1) plays.cases by auto show \<open>play \<noteq> []\<close> using n0_not_init assms(1) plays.cases by auto
qed qed
lemma strategy_from_coupledsim_retains_coupledsim: lemma strategy_from_coupledsim_retains_coupledsim:
assumes assumes
"R p0 q0" \<open>R p0 q0\<close>
"coupled_simulation R" \<open>coupled_simulation R\<close>
"initial = AttackerNode p0 q0" \<open>initial = AttackerNode p0 q0\<close>
"play \<in> plays_for_strategy (strategy_from_coupledsim R)" \<open>play \<in> plays_for_strategy (strategy_from_coupledsim R)\<close>
shows shows
"hd play = AttackerNode p q \<Longrightarrow> R p q" \<open>hd play = AttackerNode p q \<Longrightarrow> R p q\<close>
"length play > 1 \<Longrightarrow> hd (tl play) = AttackerNode p q \<Longrightarrow> R p q" \<open>length play > 1 \<Longrightarrow> hd (tl play) = AttackerNode p q \<Longrightarrow> R p q\<close>
using assms(4) using assms(4)
proof (induct arbitrary: p q rule: plays_for_strategy.induct[OF assms(4)]) proof (induct arbitrary: p q rule: plays_for_strategy.induct[OF assms(4)])
case 1 case 1
fix p q fix p q
assume "hd [initial] = AttackerNode p q" assume \<open>hd [initial] = AttackerNode p q\<close>
hence "p = p0" "q = q0" using assms(3) by auto hence \<open>p = p0\<close> \<open>q = q0\<close> using assms(3) by auto
thus "R p q" using assms(1) by simp thus \<open>R p q\<close> using assms(1) by simp
next next
case 1 case 1
fix p q fix p q
assume "1 < length [initial]" assume \<open>1 < length [initial]\<close>
hence False by auto hence False by auto
thus "R p q" .. thus \<open>R p q\<close> ..
next next
case (2 n0 play) case (2 n0 play)
hence n0play_is_play: "n0 # play \<in> plays" using strategy_plays_subset by blast hence n0play_is_play: \<open>n0 # play \<in> plays\<close> using strategy_plays_subset by blast
fix p q fix p q
assume subassms: assume subassms:
"hd (strategy_from_coupledsim R (n0 # play) # n0 # play) = AttackerNode p q" \<open>hd (strategy_from_coupledsim R (n0 # play) # n0 # play) = AttackerNode p q\<close>
"strategy_from_coupledsim R (n0 # play) # n0 # play \<open>strategy_from_coupledsim R (n0 # play) # n0 # play
\<in> plays_for_strategy (strategy_from_coupledsim R)" \<in> plays_for_strategy (strategy_from_coupledsim R)\<close>
then obtain pi qi where then obtain pi qi where
piqi_def: "hd (play) = AttackerNode pi qi" piqi_def: \<open>hd (play) = AttackerNode pi qi\<close>
"cs_game_moves (AttackerNode pi qi) n0" "play \<noteq> []" \<open>cs_game_moves (AttackerNode pi qi) n0\<close> \<open>play \<noteq> []\<close>
using attacker_followed_by_defender[OF n0play_is_play `cs_game_defender_node n0` assms(3)] using defender_preceded_by_attacker[OF n0play_is_play `cs_game_defender_node n0` assms(3)]
by blast by blast
hence "R pi qi" using 2(1,3) by simp hence \<open>R pi qi\<close> using 2(1,3) by simp
have "(\<exists> a . n0 = (DefenderStepNode a p qi) \<and> pi \<longmapsto> a p) have \<open>(\<exists> a . n0 = (DefenderStepNode a p qi) \<and> pi \<longmapsto>a p)
\<or> (n0 = (DefenderCouplingNode pi qi))" \<or> (n0 = (DefenderCouplingNode pi qi))\<close>
using piqi_def(2) 2(4,5) subassms(1) using piqi_def(2) 2(4,5) subassms(1)
by (metis cs_game_defender_node.elims(2) cs_game_moves.simps(2) list.sel(1) by (metis cs_game_defender_node.elims(2) cs_game_moves.simps(2) list.sel(1)
coupling_challenge simulation_challenge) coupling_challenge simulation_challenge)
thus "R p q" thus \<open>R p q\<close>
proof safe proof safe
fix a fix a
assume n0_def: "n0 = DefenderStepNode a p qi" "pi \<longmapsto>a p" assume n0_def: \<open>n0 = DefenderStepNode a p qi\<close> \<open>pi \<longmapsto>a p\<close>
have "strategy_from_coupledsim R (n0 # play) = have \<open>strategy_from_coupledsim R (n0 # play) =
(AttackerNode p (SOME q1 . R p q1 \<and> qi \<longmapsto>^ a q1))" (AttackerNode p (SOME q1 . R p q1 \<and> qi \<Rightarrow>^a q1))\<close>
unfolding n0_def(1) by auto unfolding n0_def(1) by auto
with subassms(1) have q_def: "q = (SOME q1. R p q1 \<and> qi \<longmapsto>^ a q1)" by auto with subassms(1) have q_def: \<open>q = (SOME q1. R p q1 \<and> qi \<Rightarrow>^a q1)\<close> by auto
have "\<exists> qii . R p qii \<and> qi \<longmapsto>^ a qii" have \<open>\<exists> qii . R p qii \<and> qi \<Rightarrow>^a qii\<close>
using n0_def(2) `R pi qi` `coupled_simulation R` using n0_def(2) `R pi qi` `coupled_simulation R`
unfolding coupled_simulation_def by blast unfolding coupled_simulation_def by blast
from someI_ex[OF this] show "R p q" unfolding q_def by blast from someI_ex[OF this] show \<open>R p q\<close> unfolding q_def by blast
next next
assume n0_def: "n0 = DefenderCouplingNode pi qi" assume n0_def: \<open>n0 = DefenderCouplingNode pi qi\<close>
have "strategy_from_coupledsim R (n0 # play) = have \<open>strategy_from_coupledsim R (n0 # play) =
(AttackerNode (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1) pi)" (AttackerNode (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1) pi)\<close>
unfolding n0_def(1) by auto unfolding n0_def(1) by auto
with subassms(1) have qp_def: "p = (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1)" "q = pi" by auto with subassms(1) have qp_def: \<open>p = (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1)\<close> \<open>q = pi\<close> by auto
have "\<exists> q1 . R q1 pi \<and> qi \<longmapsto>* tau q1" have \<open>\<exists> q1 . R q1 pi \<and> qi \<longmapsto>* tau q1\<close>
using n0_def `R pi qi` `coupled_simulation R` using n0_def `R pi qi` `coupled_simulation R`
unfolding coupled_simulation_def by blast unfolding coupled_simulation_def by blast
from someI_ex[OF this] show "R p q" unfolding qp_def by blast from someI_ex[OF this] show \<open>R p q\<close> unfolding qp_def by blast
qed qed
next next
case (2 n0 play) case (2 n0 play)
fix p q fix p q
assume "hd (tl (strategy_from_coupledsim R (n0 # play) # n0 # play)) = AttackerNode p q" assume \<open>hd (tl (strategy_from_coupledsim R (n0 # play) # n0 # play)) = AttackerNode p q\<close>
hence False using 2(4) by auto hence False using 2(4) by auto
thus "R p q" .. thus \<open>R p q\<close> ..
next next
case (3 n1 play n1') case (3 n1 play n1')
fix p q fix p q
assume "hd (n1' # n1 # play) = AttackerNode p q" assume \<open>hd (n1' # n1 # play) = AttackerNode p q\<close>
hence False using 3(4,5) unfolding player1_position_def hence False using 3(4,5) unfolding player1_position_def
by (metis cs_game_moves_no_step(5) cs_game_defender_node.elims(3) list.sel(1)) by (metis cs_game_moves_no_step(5) cs_game_defender_node.elims(3) list.sel(1))
thus "R p q" .. thus \<open>R p q\<close> ..
next next
case (3 n1 play n1') case (3 n1 play n1')
fix p q fix p q
assume "hd (tl (n1' # n1 # play)) = AttackerNode p q" assume \<open>hd (tl (n1' # n1 # play)) = AttackerNode p q\<close>
thus "R p q" using 3(1,2) by auto thus \<open>R p q\<close> using 3(1,2) by auto
qed qed
lemma strategy_from_coupledsim_sound: lemma strategy_from_coupledsim_sound:
assumes assumes
"R p0 q0" \<open>R p0 q0\<close>
"coupled_simulation R" \<open>coupled_simulation R\<close>
"initial = AttackerNode p0 q0" \<open>initial = AttackerNode p0 q0\<close>
shows shows
"sound_strategy (strategy_from_coupledsim R)" \<open>sound_strategy (strategy_from_coupledsim R)\<close>
unfolding sound_strategy_def unfolding sound_strategy_def
proof clarify proof clarify
fix n0 play fix n0 play
assume subassms: assume subassms:
"n0 # play \<in> plays_for_strategy(strategy_from_coupledsim R)" \<open>n0 # play \<in> plays_for_strategy(strategy_from_coupledsim R)\<close>
"cs_game_defender_node n0" \<open>cs_game_defender_node n0\<close>
then obtain pi qi where then obtain pi qi where
piqi_def: "hd (play) = AttackerNode pi qi" piqi_def: \<open>hd (play) = AttackerNode pi qi\<close>
"cs_game_moves (AttackerNode pi qi) n0" "play \<noteq> []" \<open>cs_game_moves (AttackerNode pi qi) n0\<close> \<open>play \<noteq> []\<close>
using attacker_followed_by_defender[OF _ `cs_game_defender_node n0` assms(3)] using defender_preceded_by_attacker[OF _ `cs_game_defender_node n0` assms(3)]
strategy_plays_subset by blast strategy_plays_subset by blast
hence "R pi qi" hence \<open>R pi qi\<close>
using strategy_from_coupledsim_retains_coupledsim[OF assms] list.sel subassms by auto using strategy_from_coupledsim_retains_coupledsim[OF assms] list.sel subassms by auto
have "(\<exists> a p . n0 = (DefenderStepNode a p qi) \<and> pi \<longmapsto> a p) have \<open>(\<exists> a p . n0 = (DefenderStepNode a p qi) \<and> pi \<longmapsto>a p)
\<or> (n0 = (DefenderCouplingNode pi qi))" \<or> (n0 = (DefenderCouplingNode pi qi))\<close>
by (metis cs_game_defender_node.elims(2) by (metis cs_game_defender_node.elims(2)
coupling_challenge simulation_challenge piqi_def(2) subassms(2)) coupling_challenge simulation_challenge piqi_def(2) subassms(2))
thus "cs_game_moves n0 (strategy_from_coupledsim R (n0 # play))" thus \<open>cs_game_moves n0 (strategy_from_coupledsim R (n0 # play))\<close>
proof safe proof safe
fix a p fix a p
assume dsn: assume dsn:
"pi \<longmapsto>a p" \<open>pi \<longmapsto>a p\<close>
"n0 = DefenderStepNode a p qi" \<open>n0 = DefenderStepNode a p qi\<close>
hence qi_spec: hence qi_spec:
"(strategy_from_coupledsim R (n0 # play)) = \<open>(strategy_from_coupledsim R (n0 # play)) =
AttackerNode p (SOME q1 . R p q1 \<and> qi \<longmapsto>^ a q1)" AttackerNode p (SOME q1 . R p q1 \<and> qi \<Rightarrow>^a q1)\<close>
by simp by simp
then obtain qii where qii_spec: then obtain qii where qii_spec:
"AttackerNode p (SOME q1 . R p q1 \<and> qi \<longmapsto>^ a q1) = AttackerNode p qii" by blast \<open>AttackerNode p (SOME q1 . R p q1 \<and> qi \<Rightarrow>^a q1) = AttackerNode p qii\<close> by blast
have "\<exists> qii . R p qii \<and> qi \<longmapsto>^ a qii" have \<open>\<exists> qii . R p qii \<and> qi \<Rightarrow>^a qii\<close>
using dsn `R pi qi` `coupled_simulation R` using dsn `R pi qi` `coupled_simulation R`
unfolding coupled_simulation_def by blast unfolding coupled_simulation_def by blast
from someI_ex[OF this] have "R p qii \<and> qi \<longmapsto>^ a qii" using qii_spec by blast from someI_ex[OF this] have \<open>R p qii \<and> qi \<Rightarrow>^a qii\<close> using qii_spec by blast
thus "cs_game_moves (DefenderStepNode a p qi) thus \<open>cs_game_moves (DefenderStepNode a p qi)
(strategy_from_coupledsim R (DefenderStepNode a p qi # play))" (strategy_from_coupledsim R (DefenderStepNode a p qi # play))\<close>
using qi_spec qii_spec unfolding dsn(2) by auto using qi_spec qii_spec unfolding dsn(2) by auto
next \<comment>\<open>coupling quite analogous.\<close> next \<comment>\<open>coupling quite analogous.\<close>
assume dcn: assume dcn:
"n0 = DefenderCouplingNode pi qi" \<open>n0 = DefenderCouplingNode pi qi\<close>
hence qi_spec: hence qi_spec:
"(strategy_from_coupledsim R (n0 # play)) = \<open>(strategy_from_coupledsim R (n0 # play)) =
AttackerNode (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1) pi" AttackerNode (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1) pi\<close>
by simp by simp
then obtain qii where qii_spec: then obtain qii where qii_spec:
"AttackerNode (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1) pi = AttackerNode qii pi" by blast \<open>AttackerNode (SOME q1 . R q1 pi \<and> qi \<longmapsto>* tau q1) pi = AttackerNode qii pi\<close> by blast
have "\<exists> qii . R qii pi \<and> qi \<longmapsto>* tau qii" have \<open>\<exists> qii . R qii pi \<and> qi \<longmapsto>* tau qii\<close>
using dcn `R pi qi` `coupled_simulation R` using dcn `R pi qi` `coupled_simulation R`
unfolding coupled_simulation_def by blast unfolding coupled_simulation_def by blast
from someI_ex[OF this] have "R qii pi \<and> qi \<longmapsto>* tau qii" using qii_spec by blast from someI_ex[OF this] have \<open>R qii pi \<and> qi \<longmapsto>* tau qii\<close> using qii_spec by blast
thus "cs_game_moves (DefenderCouplingNode pi qi) thus \<open>cs_game_moves (DefenderCouplingNode pi qi)
(strategy_from_coupledsim R (DefenderCouplingNode pi qi # play))" (strategy_from_coupledsim R (DefenderCouplingNode pi qi # play))\<close>
using qi_spec qii_spec unfolding dcn by auto using qi_spec qii_spec unfolding dcn by auto
qed qed
qed qed
lemma coupledsim_implies_winning_strategy: lemma coupledsim_implies_winning_strategy:
assumes assumes
"R p q" \<open>R p q\<close>
"coupled_simulation R" \<open>coupled_simulation R\<close>
"initial = AttackerNode p q" \<open>initial = AttackerNode p q\<close>
shows shows
"player0_winning_strategy (strategy_from_coupledsim R)" \<open>player0_winning_strategy (strategy_from_coupledsim R)\<close>
unfolding player0_winning_strategy_def unfolding player0_winning_strategy_def
proof (clarify) proof (clarify)
fix play fix play
assume subassms: assume subassms:
"play \<in> plays_for_strategy (strategy_from_coupledsim R)" \<open>play \<in> plays_for_strategy (strategy_from_coupledsim R)\<close>
"player1_wins play" \<open>player1_wins play\<close>
show "False" using subassms show \<open>False\<close> using subassms
proof (induct rule: simple_game.plays_for_strategy.induct[OF subassms(1)]) proof (induct rule: simple_game.plays_for_strategy.induct[OF subassms(1)])
case 1 case 1
then show ?case unfolding player1_wins_def using assms(3) by auto then show ?case unfolding player1_wins_def using assms(3) by auto
next next
case (2 n0 play) case (2 n0 play)