Theory Mixed_Nash_Equilibrium
theory Mixed_Nash_Equilibrium
imports
Nash_Equilibrium
"HOL-Analysis.Cartesian_Euclidean_Space"
"HOL-Analysis.Brouwer_Fixpoint"
begin
section ‹Mixed Nash Equilibria›
text ‹
This theory develops the mixed-strategy version of Nash equilibrium for finite
games whose players and pure strategies are represented by finite HOL types.
A mixed profile is a Cartesian vector indexed by player/strategy pairs.
This locale is deliberately more restrictive than the pure-game locale:
every player has the same finite pure-strategy type. In return, the profile
space is a finite Cartesian product of real coordinates, so compactness,
convexity, continuity, and Brouwer's fixed point theorem can be applied
directly.
›
type_synonym ('p, 's) mixed_profile = "real ^ ('p × 's)"
locale finite_type_game =
fixes payoff :: "'p::finite ⇒ ('p ⇒ 's::finite) ⇒ real"
begin
definition prob :: "('p, 's) mixed_profile ⇒ 'p ⇒ 's ⇒ real" where
"prob m i x = m $ (i, x)"
definition mixed_profiles :: "('p, 's) mixed_profile set" where
"mixed_profiles =
{m ∈ cbox 0 1. ∀i. (∑x∈UNIV. prob m i x) = 1}"
definition uniform_mixed_profile :: "('p, 's) mixed_profile" where
"uniform_mixed_profile = (χ ix. 1 / real CARD('s))"
definition opponent_weight :: "'p ⇒ ('p, 's) mixed_profile ⇒ ('p ⇒ 's) ⇒ real" where
"opponent_weight i m s = (∏j∈UNIV - {i}. prob m j (s j))"
definition pure_deviation_payoff ::
"'p ⇒ 's ⇒ ('p, 's) mixed_profile ⇒ real" where
"pure_deviation_payoff i x m =
(∑s∈{s. s i = x}. opponent_weight i m s * payoff i s)"
definition mixed_payoff :: "'p ⇒ ('p, 's) mixed_profile ⇒ real" where
"mixed_payoff i m =
(∑x∈UNIV. prob m i x * pure_deviation_payoff i x m)"
definition mixed_Nash_equilibrium :: "('p, 's) mixed_profile ⇒ bool" where
"mixed_Nash_equilibrium m ⟷
m ∈ mixed_profiles ∧
(∀i x. pure_deviation_payoff i x m ≤ mixed_payoff i m)"
definition excess :: "'p ⇒ 's ⇒ ('p, 's) mixed_profile ⇒ real" where
"excess i x m = max 0 (pure_deviation_payoff i x m - mixed_payoff i m)"
definition excess_sum :: "'p ⇒ ('p, 's) mixed_profile ⇒ real" where
"excess_sum i m = (∑x∈UNIV. excess i x m)"
definition nash_map :: "('p, 's) mixed_profile ⇒ ('p, 's) mixed_profile" where
"nash_map m = (χ ix. (prob m (fst ix) (snd ix) + excess (fst ix) (snd ix) m) /
(1 + excess_sum (fst ix) m))"
lemma prob_nash_map:
"prob (nash_map m) i x = (prob m i x + excess i x m) / (1 + excess_sum i m)"
by (simp add: prob_def nash_map_def)
lemma mixed_profiles_prob_nonneg:
assumes "m ∈ mixed_profiles"
shows "0 ≤ prob m i x"
using assms by (auto simp: mixed_profiles_def prob_def mem_box_cart)
lemma mixed_profiles_prob_le_one:
assumes "m ∈ mixed_profiles"
shows "prob m i x ≤ 1"
using assms by (auto simp: mixed_profiles_def prob_def mem_box_cart)
lemma mixed_profiles_sum_prob:
assumes "m ∈ mixed_profiles"
shows "(∑x∈UNIV. prob m i x) = 1"
using assms by (auto simp: mixed_profiles_def)
lemma prob_uniform_mixed_profile [simp]:
"prob uniform_mixed_profile i x = 1 / real CARD('s)"
by (simp add: prob_def uniform_mixed_profile_def)
lemma uniform_mixed_profile_in_mixed_profiles [simp]:
"uniform_mixed_profile ∈ mixed_profiles"
proof -
have card_pos: "0 < real CARD('s)"
by simp
have prob_le_one: "1 / real CARD('s) ≤ 1"
using card_pos by (simp add: divide_simps)
have sum_one: "(∑x∈UNIV. prob uniform_mixed_profile i x) = 1" for i
using card_pos by simp
show ?thesis
using card_pos prob_le_one sum_one
by (auto simp: mixed_profiles_def prob_def uniform_mixed_profile_def mem_box_cart)
qed
lemma excess_nonneg [simp]: "0 ≤ excess i x m"
by (simp add: excess_def)
lemma excess_sum_nonneg [simp]: "0 ≤ excess_sum i m"
by (simp add: excess_sum_def sum_nonneg)
lemma denom_pos [simp]: "0 < 1 + excess_sum i m"
using excess_sum_nonneg[of i m] by linarith
lemma nash_map_in_mixed_profiles:
assumes m: "m ∈ mixed_profiles"
shows "nash_map m ∈ mixed_profiles"
proof -
have nonneg: "0 ≤ prob (nash_map m) i x" for i x
using mixed_profiles_prob_nonneg[OF m, of i x]
by (simp add: prob_nash_map divide_nonneg_pos)
have le_one: "prob (nash_map m) i x ≤ 1" for i x
proof -
have ex_le: "excess i x m ≤ excess_sum i m"
unfolding excess_sum_def by (intro member_le_sum) auto
have "prob m i x + excess i x m ≤ 1 + excess_sum i m"
using mixed_profiles_prob_le_one[OF m, of i x] ex_le by linarith
then show ?thesis
by (simp add: prob_nash_map field_simps)
qed
have sum_one: "(∑x∈UNIV. prob (nash_map m) i x) = 1" for i
proof -
have "(∑x∈UNIV. prob (nash_map m) i x) =
(∑x∈UNIV. (prob m i x + excess i x m) / (1 + excess_sum i m))"
by (simp add: prob_nash_map)
also have "… =
((∑x∈UNIV. prob m i x) + excess_sum i m) / (1 + excess_sum i m)"
by (simp add: sum_divide_distrib[symmetric] sum.distrib excess_sum_def)
also have "… = 1"
by (simp add: add_nonneg_eq_0_iff m mixed_profiles_sum_prob)
finally show ?thesis .
qed
show ?thesis
using nonneg le_one sum_one
by (auto simp: mixed_profiles_def prob_def mem_box_cart)
qed
lemma continuous_prob:
"continuous_on S (λm. prob m i x)"
by (simp add: prob_def) (intro continuous_intros)
lemma continuous_opponent_weight:
"continuous_on S (λm. opponent_weight i m s)"
unfolding opponent_weight_def
by (intro continuous_intros continuous_prob)
lemma continuous_pure_deviation_payoff:
"continuous_on S (λm. pure_deviation_payoff i x m)"
unfolding pure_deviation_payoff_def
by (intro continuous_intros continuous_opponent_weight)
lemma continuous_mixed_payoff:
"continuous_on S (λm. mixed_payoff i m)"
unfolding mixed_payoff_def
by (intro continuous_intros continuous_prob continuous_pure_deviation_payoff)
lemma continuous_excess:
"continuous_on S (λm. excess i x m)"
unfolding excess_def
by (intro continuous_intros continuous_pure_deviation_payoff continuous_mixed_payoff)
lemma continuous_excess_sum:
"continuous_on S (λm. excess_sum i m)"
unfolding excess_sum_def
by (intro continuous_intros continuous_excess)
lemma continuous_nash_map:
"continuous_on mixed_profiles nash_map"
proof -
have nz: "m ∈ mixed_profiles ⟹ 1 + excess_sum (fst ix) m ≠ 0" for ix m
using denom_pos[of "fst ix" m] by linarith
show ?thesis
unfolding nash_map_def
apply (intro continuous_intros continuous_prob continuous_excess continuous_excess_sum)
using nz by blast
qed
lemma mixed_profiles_closed: "closed mixed_profiles"
proof -
have closed_constraint: "closed {m. (∑x∈UNIV. prob m i x) = 1}" for i
by (intro closed_Collect_eq continuous_intros continuous_prob)
have eq: "mixed_profiles =
cbox 0 1 ∩ (⋂i∈(UNIV :: 'p set). {m. (∑x∈UNIV. prob m i x) = 1})"
by (auto simp: mixed_profiles_def)
show ?thesis
unfolding eq using closed_constraint by (auto intro!: closed_Int closed_INT closed_cbox)
qed
lemma mixed_profiles_compact: "compact mixed_profiles"
proof -
have "mixed_profiles ⊆ cbox 0 1"
by (auto simp: mixed_profiles_def)
then show ?thesis
using compact_cbox mixed_profiles_closed compact_eq_bounded_closed bounded_cbox bounded_subset
by blast
qed
lemma mixed_profiles_convex: "convex mixed_profiles"
proof (rule convexI)
fix m n :: "('p, 's) mixed_profile"
fix u v :: real
assume mn: "m ∈ mixed_profiles" "n ∈ mixed_profiles"
and uv: "0 ≤ u" "0 ≤ v" "u + v = 1"
have in_box: "u *⇩R m + v *⇩R n ∈ cbox 0 1"
proof (auto simp: mem_box_cart)
fix a b
have "0 ≤ m $ (a, b)" "0 ≤ n $ (a, b)"
using mn by (auto simp: mixed_profiles_def mem_box_cart)
then show "0 ≤ u * m $ (a, b) + v * n $ (a, b)"
using uv by (intro add_nonneg_nonneg mult_nonneg_nonneg) auto
next
fix a b
have m_le: "m $ (a, b) ≤ 1" and n_le: "n $ (a, b) ≤ 1"
using mn by (auto simp: mixed_profiles_def mem_box_cart)
have "u * m $ (a, b) ≤ u"
using uv m_le by (metis mult.right_neutral mult_left_mono)
moreover have "v * n $ (a, b) ≤ v"
using uv n_le by (metis mult.right_neutral mult_left_mono)
ultimately show "u * m $ (a, b) + v * n $ (a, b) ≤ 1"
using uv by linarith
qed
have sum_one: "(∑x∈UNIV. prob (u *⇩R m + v *⇩R n) i x) = 1" for i
proof -
have "(∑x∈UNIV. prob (u *⇩R m + v *⇩R n) i x) =
u * (∑x∈UNIV. prob m i x) + v * (∑x∈UNIV. prob n i x)"
by (simp add: prob_def sum.distrib sum_distrib_left)
also have "… = 1"
by (simp add: mixed_profiles_sum_prob mn uv)
finally show ?thesis .
qed
show "u *⇩R m + v *⇩R n ∈ mixed_profiles"
using in_box sum_one by (auto simp: mixed_profiles_def)
qed
lemma mixed_profiles_nonempty: "mixed_profiles ≠ {}"
using uniform_mixed_profile_in_mixed_profiles by blast
lemma mixed_Nash_equilibrium_profile:
assumes "mixed_Nash_equilibrium m"
shows "m ∈ mixed_profiles"
using assms by (simp add: mixed_Nash_equilibrium_def)
lemma mixed_Nash_equilibriumD:
assumes "mixed_Nash_equilibrium m"
shows "pure_deviation_payoff i x m ≤ mixed_payoff i m"
using assms by (simp add: mixed_Nash_equilibrium_def)
lemma mixed_Nash_support_payoff_eq:
assumes ne: "mixed_Nash_equilibrium m" and px: "prob m i x > 0"
shows "pure_deviation_payoff i x m = mixed_payoff i m"
proof -
have m: "m ∈ mixed_profiles"
using ne by (rule mixed_Nash_equilibrium_profile)
have gap_nonneg:
"0 ≤ prob m i y * (mixed_payoff i m - pure_deviation_payoff i y m)" for y
using mixed_profiles_prob_nonneg[OF m, of i y] mixed_Nash_equilibriumD[OF ne, of i y]
by (intro mult_nonneg_nonneg) auto
have "(∑y∈UNIV. prob m i y * (mixed_payoff i m - pure_deviation_payoff i y m)) =
(∑y∈UNIV. prob m i y * mixed_payoff i m) -
(∑y∈UNIV. prob m i y * pure_deviation_payoff i y m)"
by (simp add: algebra_simps sum_subtractf)
also have "… =
(∑y∈UNIV. prob m i y) * mixed_payoff i m - mixed_payoff i m"
unfolding mixed_payoff_def by (simp add: sum_distrib_right)
also have "… =
mixed_payoff i m * (∑y∈UNIV. prob m i y) - mixed_payoff i m"
by (simp add: mult.commute)
also have "… = 0"
using mixed_profiles_sum_prob[OF m, of i] by simp
finally have gaps_zero:
"⋀y. y ∈ UNIV ⟹
prob m i y * (mixed_payoff i m - pure_deviation_payoff i y m) = 0"
using gap_nonneg by (simp add: sum_nonneg_eq_0_iff)
have "mixed_payoff i m - pure_deviation_payoff i x m = 0"
using gaps_zero[of x] px by simp
then show ?thesis
by simp
qed
lemma mixed_Nash_zero_probability_if_less:
assumes ne: "mixed_Nash_equilibrium m"
and less: "pure_deviation_payoff i x m < mixed_payoff i m"
shows "prob m i x = 0"
proof (rule ccontr)
assume "prob m i x ≠ 0"
moreover have "0 ≤ prob m i x"
using mixed_Nash_equilibrium_profile[OF ne] by (rule mixed_profiles_prob_nonneg)
ultimately have "pure_deviation_payoff i x m = mixed_payoff i m"
using mixed_Nash_support_payoff_eq[OF ne] by simp
then show False
using less by simp
qed
definition dirac_mixed_profile :: "('p ⇒ 's) ⇒ ('p, 's) mixed_profile" where
"dirac_mixed_profile s = (χ ix. if snd ix = s (fst ix) then 1 else 0)"
lemma prob_dirac_mixed_profile [simp]:
"prob (dirac_mixed_profile s) i x = (if x = s i then 1 else 0)"
by (simp add: prob_def dirac_mixed_profile_def)
lemma dirac_mixed_profile_in_mixed_profiles [simp]:
"dirac_mixed_profile s ∈ mixed_profiles"
by (auto simp: mixed_profiles_def prob_def dirac_mixed_profile_def mem_box_cart)
lemma opponent_weight_dirac_mixed_profile:
"opponent_weight i (dirac_mixed_profile s) t =
(if ∀j. j ≠ i ⟶ t j = s j then 1 else 0)"
proof (cases "∀j. j ≠ i ⟶ t j = s j")
case True
then show ?thesis
by (auto simp: opponent_weight_def)
next
case False
then obtain j where j: "j ≠ i" "t j ≠ s j"
by blast
have j_in: "j ∈ UNIV - {i}"
using j by simp
have j_zero: "prob (dirac_mixed_profile s) j (t j) = 0"
using j by simp
have zero_ex: "∃k∈UNIV - {i}. prob (dirac_mixed_profile s) k (t k) = 0"
using j_in j_zero by blast
have fin: "finite (UNIV - {i})"
by simp
have "(∏j∈UNIV - {i}. prob (dirac_mixed_profile s) j (t j)) = 0"
by (rule prod_zero[OF fin zero_ex])
then show ?thesis
using False by (simp add: opponent_weight_def)
qed
lemma pure_deviation_payoff_dirac_mixed_profile:
"pure_deviation_payoff i x (dirac_mixed_profile s) = payoff i (s(i := x))"
proof -
have term_eq:
"⋀t. t ∈ {t. t i = x} ⟹
opponent_weight i (dirac_mixed_profile s) t * payoff i t =
(if t = s(i := x) then payoff i (s(i := x)) else 0)"
proof -
fix t
assume t_in: "t ∈ {t. t i = x}"
show "opponent_weight i (dirac_mixed_profile s) t * payoff i t =
(if t = s(i := x) then payoff i (s(i := x)) else 0)"
proof (cases "∀j. j ≠ i ⟶ t j = s j")
case True
then have "t = s(i := x)"
using t_in by (auto simp: fun_eq_iff)
then show ?thesis
using True by (simp add: opponent_weight_dirac_mixed_profile)
next
case False
then have "t ≠ s(i := x)"
by (auto simp: fun_eq_iff)
moreover have "opponent_weight i (dirac_mixed_profile s) t = 0"
using False by (simp add: opponent_weight_dirac_mixed_profile)
then show ?thesis
using calculation by simp
qed
qed
have "pure_deviation_payoff i x (dirac_mixed_profile s) =
(∑t∈{t. t i = x}. if t = s(i := x) then payoff i (s(i := x)) else 0)"
unfolding pure_deviation_payoff_def
by (intro sum.cong) (auto simp: term_eq)
also have "… = payoff i (s(i := x))"
by simp
finally show ?thesis .
qed
lemma mixed_payoff_dirac_mixed_profile:
"mixed_payoff i (dirac_mixed_profile s) = payoff i s"
proof -
have "mixed_payoff i (dirac_mixed_profile s) =
(∑x∈UNIV. if x = s i then payoff i (s(i := x)) else 0)"
unfolding mixed_payoff_def
by (intro sum.cong) (simp_all add: pure_deviation_payoff_dirac_mixed_profile)
also have "… = payoff i s"
by simp
finally show ?thesis .
qed
lemma dirac_mixed_Nash_equilibrium:
assumes "⋀i x. payoff i (s(i := x)) ≤ payoff i s"
shows "mixed_Nash_equilibrium (dirac_mixed_profile s)"
using assms
by (auto simp: mixed_Nash_equilibrium_def
pure_deviation_payoff_dirac_mixed_profile mixed_payoff_dirac_mixed_profile)
lemma fixed_point_imp_excess_zero:
assumes m: "m ∈ mixed_profiles" and fp: "nash_map m = m"
shows "excess i x m = 0"
proof -
let ?G = "excess_sum i m"
have ex_eq: "excess i y m = prob m i y * ?G" for y
proof -
have eq: "prob m i y = (prob m i y + excess i y m) / (1 + ?G)"
using arg_cong[OF fp, of "λm. prob m i y"] by (simp add: prob_nash_map)
then have mult_eq: "prob m i y * (1 + ?G) = prob m i y + excess i y m"
using denom_pos[of i m] by (simp add: field_simps)
then show "excess i y m = prob m i y * ?G"
by (simp add: algebra_simps)
qed
show ?thesis
proof (cases "?G = 0")
case True
then show ?thesis
using ex_eq[of x] by simp
next
case False
then have G_pos: "?G > 0"
using excess_sum_nonneg[of i m] by linarith
have pos_imp:
"pure_deviation_payoff i x m = mixed_payoff i m + prob m i x * ?G"
if "prob m i x > 0" for x
proof -
have ex_pos: "excess i x m > 0"
using that G_pos ex_eq[of x] by simp
then have "pure_deviation_payoff i x m - mixed_payoff i m = excess i x m"
by (simp add: excess_def)
then show ?thesis
using ex_eq[of x] by simp
qed
have payoff_eq:
"prob m i y * pure_deviation_payoff i y m =
prob m i y * mixed_payoff i m + ?G * (prob m i y)⇧2" for y
proof (cases "prob m i y = 0")
case True
then show ?thesis
by simp
next
case False
have "0 ≤ prob m i y"
by (rule mixed_profiles_prob_nonneg[OF m])
with False have "prob m i y > 0"
by simp
then show ?thesis
using pos_imp[of y] by (simp add: algebra_simps power2_eq_square)
qed
have payoff_average:
"mixed_payoff i m =
mixed_payoff i m * (∑y∈UNIV. prob m i y) +
?G * (∑y∈UNIV. (prob m i y)⇧2)"
proof -
have "mixed_payoff i m =
(∑y∈UNIV. prob m i y * pure_deviation_payoff i y m)"
by (simp add: mixed_payoff_def)
also have "… =
(∑y∈UNIV.
prob m i y * mixed_payoff i m + ?G * (prob m i y)⇧2)"
by (intro sum.cong) (simp_all add: payoff_eq)
also have "… =
(∑y∈UNIV. prob m i y * mixed_payoff i m) +
(∑y∈UNIV. ?G * (prob m i y)⇧2)"
by (simp add: sum.distrib)
also have "… =
(∑y∈UNIV. prob m i y) * mixed_payoff i m +
?G * (∑y∈UNIV. (prob m i y)⇧2)"
by (simp add: sum_distrib_left sum_distrib_right)
also have "… =
mixed_payoff i m * (∑y∈UNIV. prob m i y) +
?G * (∑y∈UNIV. (prob m i y)⇧2)"
by (simp add: mult.commute)
finally show ?thesis .
qed
have "mixed_payoff i m =
mixed_payoff i m + ?G * (∑y∈UNIV. (prob m i y)⇧2)"
using payoff_average mixed_profiles_sum_prob[OF m, of i] by simp
then have G_squares_zero: "?G * (∑y∈UNIV. (prob m i y)⇧2) = 0"
by simp
have sq_zero: "(∑y∈UNIV. (prob m i y)⇧2) = 0"
using G_pos G_squares_zero by simp
have "∃x. prob m i x > 0"
proof (rule ccontr)
assume no_pos: "¬ (∃x. prob m i x > 0)"
have zero: "prob m i x = 0" for x
by (smt (verit) m mixed_profiles_prob_nonneg no_pos)
have "(∑x∈UNIV. prob m i x) = 0"
by (simp add: zero)
then show False
using mixed_profiles_sum_prob[OF m, of i] by simp
qed
then obtain y where y: "prob m i y > 0"
by blast
have "0 < (prob m i y)⇧2"
using y by simp
moreover have "(prob m i y)⇧2 ≤ (∑x∈UNIV. (prob m i x)⇧2)"
by (intro member_le_sum) auto
ultimately show ?thesis
using sq_zero by simp
qed
qed
theorem exists_mixed_Nash_equilibrium:
"∃m∈mixed_profiles. mixed_Nash_equilibrium m"
proof -
obtain m where m: "m ∈ mixed_profiles" and fp: "nash_map m = m"
proof (rule brouwer[
OF mixed_profiles_compact mixed_profiles_convex mixed_profiles_nonempty continuous_nash_map])
show "nash_map ∈ mixed_profiles → mixed_profiles"
using nash_map_in_mixed_profiles by auto
qed
have no_excess: "excess i x m = 0" for i x
by (rule fixed_point_imp_excess_zero[OF m fp])
have deviation_le: "pure_deviation_payoff i x m ≤ mixed_payoff i m" for i x
proof -
have "pure_deviation_payoff i x m - mixed_payoff i m
≤ max 0 (pure_deviation_payoff i x m - mixed_payoff i m)"
by simp
also have "… = 0"
using no_excess[of i x] by (simp add: excess_def)
finally show ?thesis
by simp
qed
have "mixed_Nash_equilibrium m"
using m deviation_le by (auto simp: mixed_Nash_equilibrium_def)
then show ?thesis
using m by blast
qed
end
end