Theory GaleStewartDefensiveStrategies
subsection ‹Defensive strategies›
text ‹ A strategy is defensive if a player can avoid reaching winning positions.
If the opponent is not already in a winning position, such defensive strategies exist.
In closed games, a defensive strategy is winning for the closed player,
so these strategies are a crucial step towards proving that such games are determined.
›
theory GaleStewartDefensiveStrategies
imports GaleStewartGames
begin
context GSgame
begin
definition move_defensive_by_Even where
"move_defensive_by_Even m p ≡ even (length p) ⟶ ¬ winning_position_Odd (p @ [m])"
definition move_defensive_by_Odd where
"move_defensive_by_Odd m p ≡ odd (length p) ⟶ ¬ winning_position_Even (p @ [m])"
lemma defensive_move_exists_for_Even:
assumes [intro]:"position p"
shows "winning_position_Odd p ∨ (∃ m. move_defensive_by_Even m p)" (is "?w ∨ ?d")
proof(cases "length p = 2*N ∨ odd (length p)")
case False
hence pl[intro]:"length p < 2*N"
and ev[intro]:"even (length p)" using assms[unfolded position_def] by auto
show ?thesis proof(rule impI[of "¬ ?d ⟶ ¬ ?w ⟶ False", rule_format], force)
assume not_def:"¬ ?d"
from not_def[unfolded move_defensive_by_Even_def]
have "∀ m. ∃σ. strategy_winning_by_Odd σ (p @ [m])" by blast
from choice[OF this] obtain σ⇩o where
str_Odd:"⋀ m. strategy_winning_by_Odd (σ⇩o m) (p @ [m])" by blast
define σ where "σ p' = σ⇩o (p' ! length p) p'" for p'
assume not_win:"¬ ?w"
from not_win[unfolded move_defensive_by_Even_def strategy_winning_by_Odd_def]
obtain σ⇩e where
str_Even:"induced_play (joint_strategy σ⇩e σ) p ∈ A"
(is "?pe p ∈ A")
by blast
let ?pnext = "(p @ [joint_strategy σ⇩e σ p])"
{ fix p' m
assume "prefix (p @ [m]) p'"
hence "(p' ! length p) = m"
unfolding prefix_def by auto
}
hence eq_a:"∀ p'. prefix ?pnext p' ⟶ p' @ [joint_strategy σ⇩e σ p'] =
p' @ [joint_strategy σ⇩e (σ⇩o (joint_strategy σ⇩e σ p)) p']"
unfolding joint_strategy_def σ_def by auto
have simps:"?pe p = ?pe (p @ [joint_strategy σ⇩e σ p])"
unfolding induced_play_def by auto
from str_Even str_Odd[of "joint_strategy σ⇩e σ p", unfolded strategy_winning_by_Odd_def, rule_format, of "σ⇩e"]
induced_play_eq[OF eq_a]
show False unfolding simps by auto
qed
qed (auto simp: move_defensive_by_Even_def strategy_winning_by_Even_def position_maxlength_cannotbe_augmented)
lemma defensive_move_exists_for_Odd:
assumes [intro]:"position p"
shows "winning_position_Even p ∨ (∃ m. move_defensive_by_Odd m p)" (is "?w ∨ ?d")
proof(cases "length p = 2*N ∨ even (length p)")
case False
hence pl[intro]:"length p < 2*N"
and ev[intro]:"odd (length p)" using assms[unfolded position_def] by auto
show ?thesis proof(rule impI[of "¬ ?d ⟶ ¬ ?w ⟶ False", rule_format], force)
assume not_def:"¬ ?d"
from not_def[unfolded move_defensive_by_Odd_def]
have "∀ m. ∃σ. strategy_winning_by_Even σ (p @ [m])" by blast
from choice[OF this] obtain σ⇩e where
str_Even:"⋀ m. strategy_winning_by_Even (σ⇩e m) (p @ [m])" by blast
define σ where "σ p' = σ⇩e (p' ! length p) p'" for p'
assume not_win:"¬ ?w"
from not_win[unfolded move_defensive_by_Odd_def strategy_winning_by_Even_def]
obtain σ⇩o where
str_Odd:"induced_play (joint_strategy σ σ⇩o) p ∉ A"
(is "?pe p ∉ A")
by blast
let ?strat = "joint_strategy σ σ⇩o"
let ?pnext = "(p @ [?strat p])"
{ fix p' m
assume "prefix (p @ [m]) p'"
hence "(p' ! length p) = m"
unfolding prefix_def by auto
}
hence eq_a:"∀ p'. prefix ?pnext p' ⟶ p' @ [?strat p'] =
p' @ [joint_strategy (σ⇩e (?strat p)) σ⇩o p']"
unfolding joint_strategy_def σ_def by auto
have simps:"?pe p = ?pe (p @ [?strat p])"
unfolding induced_play_def by auto
from str_Odd str_Even[of "?strat p", unfolded strategy_winning_by_Even_def, rule_format]
induced_play_eq[OF eq_a]
show False unfolding simps by auto
qed
qed (auto simp: move_defensive_by_Odd_def strategy_winning_by_Odd_def position_maxlength_cannotbe_augmented)
definition defensive_strategy_Even where
"defensive_strategy_Even p ≡ SOME m. move_defensive_by_Even m p"
definition defensive_strategy_Odd where
"defensive_strategy_Odd p ≡ SOME m. move_defensive_by_Odd m p"
lemma position_augment:
assumes "position ((augment_list f ^^ n) p)"
shows "position p"
using assms length_augment_list[of n f p] unfolding position_def
by fastforce
lemma defensive_strategy_Odd:
assumes "¬ winning_position_Even p"
shows "¬ winning_position_Even (((augment_list (joint_strategy σ⇩e defensive_strategy_Odd)) ^^ n) p)"
proof -
show ?thesis using assms proof(induct n arbitrary:p)
case (Suc n)
show ?case proof(cases "position p")
case True
from Suc.prems defensive_move_exists_for_Odd[OF True] defensive_strategy_Odd_def someI
have "move_defensive_by_Odd (defensive_strategy_Odd p) p" by metis
from this[unfolded move_defensive_by_Odd_def] Suc.prems
non_winning_moves_remains_non_winning_Even[of p]
have "¬ winning_position_Even (p @ [joint_strategy σ⇩e defensive_strategy_Odd p])"
by (simp add: joint_strategy_def True)
with Suc.hyps[of "p @ [joint_strategy σ⇩e defensive_strategy_Odd p]"]
show ?thesis unfolding funpow_Suc_right comp_def by fastforce
qed (insert position_augment,blast)
qed auto
qed
lemma defensive_strategy_Even:
assumes "¬ winning_position_Odd p"
shows "¬ winning_position_Odd (((augment_list (joint_strategy defensive_strategy_Even σ⇩o)) ^^ n) p)"
proof -
show ?thesis using assms proof(induct n arbitrary:p)
case (Suc n)
show ?case proof(cases "position p")
case True
from Suc.prems defensive_move_exists_for_Even[OF True] defensive_strategy_Even_def someI
have "move_defensive_by_Even (defensive_strategy_Even p) p" by metis
from this[unfolded move_defensive_by_Even_def] Suc.prems
non_winning_moves_remains_non_winning_Odd[of p]
have "¬ winning_position_Odd (p @ [joint_strategy defensive_strategy_Even σ⇩o p])"
by (simp add: joint_strategy_def True)
with Suc.hyps[of "p @ [joint_strategy defensive_strategy_Even σ⇩o p]"]
show ?thesis unfolding funpow_Suc_right comp_def by fastforce
qed (insert position_augment,blast)
qed auto
qed
end
locale closed_GSgame = GSgame +
assumes closed:"e ∈ A ⟹ ∃ p. lprefix (llist_of p) e ∧ (∀ e'. lprefix (llist_of p) e' ⟶ llength e' = 2*N ⟶ e' ∈ A)"
locale finite_GSgame = GSgame +
assumes fin:"N ≠ ∞"
begin
text ‹ Finite games are closed games. As a corollary to the GS theorem, this lets us conclude that finite games are determined. ›
sublocale closed_GSgame
proof
fix e assume eA:"e ∈ A"
let ?p = "list_of e"
from eA have len:"llength e = 2*N" using length by blast
with fin have p:"llist_of ?p = e"
by (metis llist_of_list_of mult_2 not_lfinite_llength plus_eq_infty_iff_enat)
hence pfx:"lprefix (llist_of ?p) e" by auto
{ fix e'
assume "lprefix (llist_of ?p) e'" "llength e' = 2 * N"
hence "e' = e" using len by (metis lprefix_llength_eq_imp_eq p)
with eA have "e' ∈ A" by simp
}
with pfx show "∃p. lprefix (llist_of p) e ∧ (∀e'. lprefix (llist_of p) e' ⟶ llength e' = 2 * N ⟶ e' ∈ A)"
by blast
qed
end
context closed_GSgame begin
lemma never_winning_is_losing_even:
assumes "position p" "∀ n. ¬ winning_position_Even (((augment_list σ) ^^ n) p)"
shows "induced_play σ p ∉ A"
proof
assume "induced_play σ p ∈ A"
from closed[OF this] obtain p' where
p':"lprefix (llist_of p') (induced_play σ p)"
"⋀ e. lprefix (llist_of p') e ⟹ llength e = 2 * N ⟹ e ∈ A" by blast
from lprefix_llength_le[OF p'(1)] have lp':"llength (llist_of p') ≤ 2 * N" by auto
show False proof (cases "length p' ≤ length p")
case True
hence "llength (llist_of p') ≤ llength (llist_of p)" by auto
from lprefix_llength_lprefix[OF p'(1) _ this]
induced_play_is_lprefix[OF assms(1)]
lprefix_trans
have pref:"lprefix (llist_of p') (induced_play strat p)" for strat by blast
from assms(2)[rule_format,of 0] assms(1) have "¬ strategy_winning_by_Even σ p" for σ by auto
from this[unfolded strategy_winning_by_Even_def] obtain strat where
strat:"induced_play strat p ∉ A" by auto
from strat p'(2)[OF pref] show False by simp
next
case False
let ?n = "length p' - length p"
let ?pos = "(augment_list σ ^^ ?n) p"
from False have "length p' ≥ length p" by auto
hence [simp]:"length ?pos = length p'"
by (auto simp:length_augment_list)
hence pos[intro]:"position ?pos"
using False lp'(1) unfolding position_def by auto
have "llist_of p' = llist_of ?pos"
using p'(1)
by(intro lprefix_antisym[OF lprefix_llength_lprefix lprefix_llength_lprefix],auto)
hence p'_pos:"p' = ?pos" by simp
from assms(2)[rule_format,of ?n] assms(1) have "¬ strategy_winning_by_Even σ ?pos" for σ by auto
from this[unfolded strategy_winning_by_Even_def] obtain strat where
strat:"induced_play strat ?pos ∉ A" by auto
from p'_pos induced_play_is_lprefix[OF pos, of strat]
have pref:"lprefix (llist_of p') (induced_play strat ?pos)" by simp
with p'(2)[OF pref] strat show False by simp
qed
qed
lemma every_position_is_determined:
assumes "position p"
shows "winning_position_Even p ∨ winning_position_Odd p" (is "?we ∨ ?wo")
proof(rule impI[of "¬ ?we ⟶ ¬ ?wo ⟶ False",rule_format],force)
assume "¬ ?we"
from defensive_strategy_Odd[OF this] never_winning_is_losing_even[OF assms]
have js_no:"induced_play
(joint_strategy s defensive_strategy_Odd) p ∉ A" for s
by auto
assume "¬ ?wo"
from this[unfolded strategy_winning_by_Odd_def] assms
have "∃ s. induced_play
(joint_strategy s defensive_strategy_Odd) p ∈ A" by simp
thus False using js_no by simp
qed
end
end