Theory SWF_Explicit
subsection ‹Social Welfare Functions with explicit lists of agents and alternatives›
theory SWF_Explicit
imports SWF_Anonymous
begin
locale linorder_election_explicit =
linorder_election agents alts
for agents :: "'agent set" and alts :: "'alt set" +
fixes agents_list :: "'agent list" and alts_list :: "'alt list"
assumes agents_list: "mset agents_list = mset_set agents"
assumes alts_list: "mset alts_list = mset_set alts"
begin
lemma distinct_alts_list: "distinct alts_list"
using alts_list by (metis finite_alts mset_eq_mset_set_imp_distinct)
lemma alts_conv_alts_list: "alts = set alts_list"
using alts_list by (metis finite_alts finite_set_mset_mset_set set_mset_mset)
lemma card_alts [simp]: "card alts = length alts_list"
using alts_list by (metis size_mset size_mset_set)
lemma distinct_agents_list: "distinct agents_list"
using agents_list by (metis finite_agents mset_eq_mset_set_imp_distinct)
lemma agents_conv_agents_list: "agents = set agents_list"
using agents_list by (metis finite_agents finite_set_mset_mset_set set_mset_mset)
lemma card_agents: "card agents = length agents_list"
using agents_list by (metis size_mset size_mset_set)
lemma mset_eq_alts_list_iff: "mset xs = mset alts_list ⟷ distinct xs ∧ set xs = alts"
by (metis alts_conv_alts_list card_alts card_distinct
mset_set_set set_mset_mset size_mset)
lemma mset_eq_agents_list_iff: "mset xs = mset agents_list ⟷ distinct xs ∧ set xs = agents"
by (metis agents_conv_agents_list card_agents card_distinct
mset_set_set set_mset_mset size_mset)
definition prefs_from_rankings
:: "'alt list list ⇒ ('agent ⇒ 'alt relation)" where
"prefs_from_rankings rs =
(λi. if i ∈ agents then of_ranking (rs ! index agents_list i) else (λ_ _. False))"
definition prefs_from_rankings_wf :: "'alt list list ⇒ bool" where
"prefs_from_rankings_wf rs ⟷
length rs = card agents ∧ list_all (λr. mset r = mset alts_list) rs"
lemma prefs_from_rankings_wf_imp_is_pref_profile [intro]:
assumes "prefs_from_rankings_wf rs"
shows "is_pref_profile (prefs_from_rankings rs)"
proof
fix i assume i: "i ∈ agents"
hence "rs ! index agents_list i ∈ set rs"
by (intro nth_mem)
(use assms in ‹auto simp: prefs_from_rankings_wf_def card_agents index_less_size_conv
simp flip: agents_conv_agents_list›)
hence "distinct (rs ! index agents_list i) ∧ set (rs ! index agents_list i) = alts"
using assms unfolding prefs_from_rankings_wf_def list.pred_set mset_eq_alts_list_iff by blast
thus "linorder_on alts (prefs_from_rankings rs i)"
using assms i by (auto simp: prefs_from_rankings_def intro!: linorder_of_ranking)
qed (use assms in ‹auto simp: prefs_from_rankings_def›)
lemma prefs_from_rankings_nth:
assumes "prefs_from_rankings_wf R1" "i < card agents"
shows "prefs_from_rankings R1 (agents_list ! i) = of_ranking (R1 ! i)"
using assms card_agents agents_conv_agents_list distinct_agents_list
unfolding prefs_from_rankings_def by (simp add: index_nth_id)
lemma prefs_from_rankings_outside:
assumes "i ∉ agents"
shows "prefs_from_rankings R1 i = (λ_ _. False)"
using assms by (auto simp: prefs_from_rankings_def)
lemma prefs_from_rankings_update:
assumes "prefs_from_rankings_wf R1" "i < card agents" "mset xs = mset alts_list"
shows "prefs_from_rankings (R1[i := xs]) =
(prefs_from_rankings R1)(agents_list ! i := of_ranking xs)"
using assms distinct_agents_list card_agents agents_conv_agents_list
index_less_size_conv[of agents_list]
unfolding prefs_from_rankings_def prefs_from_rankings_wf_def
by (auto simp: fun_eq_iff index_nth_id nth_list_update)
lemma prefs_from_rankings_wf_update:
assumes "prefs_from_rankings_wf R1" "i < card agents" "mset xs = mset alts_list"
shows "prefs_from_rankings_wf (R1[i := xs])"
using assms set_update_subset_insert[of R1 i xs] unfolding prefs_from_rankings_wf_def
by (auto simp: list.pred_set set_update_distinct)
lemma majority_prefs_from_rankings:
assumes "prefs_from_rankings_wf R"
shows "majority (prefs_from_rankings R) = majority_mset (mset (map of_ranking R))"
proof -
interpret R: pref_profile_linorder_wf agents alts "prefs_from_rankings R"
using assms by blast
have "majority (prefs_from_rankings R) =
majority_mset (image_mset (prefs_from_rankings R) (mset_set agents))"
by (rule R.majority_conv_majority_mset) auto
also have "image_mset (prefs_from_rankings R) (mset_set agents) =
image_mset (of_ranking ∘ (λi. R ! i) ∘ index agents_list) (mset_set agents)"
by (intro image_mset_cong)
(use assms in ‹auto simp: prefs_from_rankings_wf_def prefs_from_rankings_def›)
also have "… = image_mset of_ranking (image_mset (λi. R ! i) (image_mset (index agents_list) (mset agents_list)))"
by (simp add: image_mset.compositionality o_def agents_list)
also have "image_mset (λi. R ! i) (image_mset (index agents_list) (mset agents_list)) =
mset (map (λi. R ! i) (map (index agents_list) agents_list))"
unfolding mset_map by simp
also have "map (index agents_list) agents_list = [0..<length R]"
by (subst map_index_self)
(use distinct_agents_list card_agents assms in ‹simp_all add: prefs_from_rankings_wf_def›)
also have "map (λi. R ! i) … = R"
by (rule map_nth)
finally show ?thesis by simp
qed
lemma majority_prefs_from_rankings_eq_of_ranking:
assumes "prefs_from_rankings_wf R" "majority_rel_mset (mset R) ys"
shows "majority (prefs_from_rankings R) = of_ranking ys"
proof -
have "of_ranking ys = majority_mset (image_mset of_ranking (mset R))"
using assms(2) by (auto simp: majority_rel_mset_def)
also have "… = majority (prefs_from_rankings R)"
by (subst majority_prefs_from_rankings) (use assms in simp_all)
finally show ?thesis ..
qed
lemma majority_rel_mset_imp_mset:
assumes "prefs_from_rankings_wf R" "majority_rel_mset (mset R) xs"
shows "mset xs = mset alts_list"
proof -
interpret R: pref_profile_linorder_wf agents alts "prefs_from_rankings R"
by (rule prefs_from_rankings_wf_imp_is_pref_profile) fact
have "majority (prefs_from_rankings R) = of_ranking xs"
by (rule majority_prefs_from_rankings_eq_of_ranking) fact+
thus ?thesis
by (metis R.majority_not_outside(2) R.majority_refl assms(2) majority_rel_mset_def
mset_eq_alts_list_iff of_ranking_imp_in_set(2) of_ranking_refl
order_antisym_conv subset_iff)
qed
end
locale social_welfare_function_explicit =
social_welfare_function agents alts swf +
linorder_election_explicit agents alts agents_list alts_list
for agents :: "'agent set" and alts :: "'alt set" and swf agents_list alts_list
begin
definition swf' :: "'alt list list ⇒ 'alt list" where
"swf' R = ranking (swf (prefs_from_rankings R))"
lemma swf'_wf: "prefs_from_rankings_wf R ⟹ mset (swf' R) = mset_set alts"
unfolding swf'_def
using finite_linorder_on.distinct_ranking finite_linorder_on.set_ranking alts_list finite_alts
prefs_from_rankings_wf_imp_is_pref_profile mset_eq_alts_list_iff swf_wf' by metis
end
locale majority_consistent_swf_explicit =
social_welfare_function_explicit agents alts swf agents_list alts_list +
majority_consistent_swf agents alts swf
for agents :: "'agent set" and alts :: "'alt set" and swf agents_list alts_list
begin
lemma majority_consistent_swf':
assumes "prefs_from_rankings_wf R" "majority_rel_mset (mset R) ys"
shows "swf' R = ys"
using assms
by (metis linorder_of_ranking majority_consistent majority_prefs_from_rankings_eq_of_ranking
majority_rel_mset_imp_mset mset_eq_alts_list_iff
prefs_from_rankings_wf_imp_is_pref_profile ranking_of_ranking swf'_def)
end
locale majcons_kstratproof_swf_explicit =
social_welfare_function_explicit agents alts swf agents_list alts_list +
majcons_kstratproof_swf agents alts swf
for agents :: "'agent set" and alts :: "'alt set" and swf agents_list alts_list
begin
sublocale majority_consistent_swf_explicit ..
sublocale majority_consistent_weak_kstratproof_swf
by unfold_locales
(metis kemeny_strategyproof majority_consistent pref_profile_linorder_wf.wf_update)
lemma distinct_alts_list_aux: "distinct alts_list"
using alts_list by (metis finite_alts mset_eq_mset_set_imp_distinct)
lemma distinct_agents_list_aux: "distinct agents_list"
using agents_list by (metis finite_agents mset_eq_mset_set_imp_distinct)
lemma prefs_from_rankings_wf_iff:
"prefs_from_rankings_wf xss ⟷
length xss = length agents_list ∧ list_all (λys. mset ys = mset alts_list) xss"
unfolding prefs_from_rankings_wf_def using card_agents by simp
lemma swf'_in_all_rankings:
assumes "prefs_from_rankings_wf xss" "permutations_of_set_list alts_list = yss"
shows "list_ex (λys. swf' xss = ys) yss"
proof -
have "mset (swf' xss) = mset_set alts"
by (rule swf'_wf) fact
hence "swf' xss ∈ permutations_of_set alts"
unfolding permutations_of_set_def using alts_list mset_eq_alts_list_iff by force
also have "permutations_of_set alts = set yss"
by (metis alts_conv_alts_list distinct_alts_list assms(2)
permutations_of_list remdups_id_iff_distinct)
finally show ?thesis
unfolding list_ex_iff by blast
qed
lemma kemeny_strategyproof_swf':
assumes "prefs_from_rankings_wf R1" "i < card agents"
assumes "mset zs = mset alts_list"
assumes "xs = R1 ! i" "R2 = R1[i := zs]"
shows "swap_dist xs (swf' R1) ≤ swap_dist xs (swf' R2)"
proof -
define R1' where "R1' = prefs_from_rankings R1"
define j where "j = agents_list ! i"
have j: "j ∈ agents"
unfolding j_def using assms agents_conv_agents_list card_agents by force
have zs: "linorder_on alts (of_ranking zs)"
using assms by (intro linorder_of_ranking) (auto simp: mset_eq_alts_list_iff)
have "xs ∈ set R1"
using assms card_agents by (auto simp: prefs_from_rankings_wf_def)
hence xs: "mset xs = mset alts_list"
using assms by (auto simp: prefs_from_rankings_wf_def list.pred_set)
have R2: "prefs_from_rankings_wf R2"
using assms prefs_from_rankings_wf_update by blast
have "swap_dist_relation (R1' j) (swf (R1'(j := of_ranking zs))) ≥ swap_dist_relation (R1' j) (swf R1')"
by (rule kemeny_strategyproof) (use assms j zs in ‹auto simp: R1'_def›)
also have "R1' j = of_ranking xs"
using assms prefs_from_rankings_nth unfolding R1'_def j_def by metis
also have "R1'(j := of_ranking zs) = prefs_from_rankings R2"
using assms unfolding R1'_def j_def using prefs_from_rankings_update by metis
also have "swf R1' = of_ranking (swf' R1)"
unfolding swf'_def R1'_def
by (metis assms(1) finite_linorder_on.of_ranking_ranking
prefs_from_rankings_wf_imp_is_pref_profile swf_wf')
also have "swf (prefs_from_rankings R2) = of_ranking (swf' R2)"
unfolding swf'_def
by (metis assms(1,2,3,5) finite_linorder_on.of_ranking_ranking prefs_from_rankings_wf_update
prefs_from_rankings_wf_imp_is_pref_profile swf_wf')
also have "swap_dist_relation (of_ranking xs) (of_ranking (swf' R1)) =
swap_dist xs (swf' R1)"
using swf'_wf[of R1] alts_list assms(1) mset_eq_alts_list_iff xs
unfolding swap_dist_def by auto
also have "swap_dist_relation (of_ranking xs) (of_ranking (swf' R2)) =
swap_dist xs (swf' R2)"
using xs swf'_wf[of R2] alts_list R2 mset_eq_alts_list_iff
unfolding swap_dist_def by auto
finally show ?thesis .
qed
lemma kemeny_strategyproof_swf'_aux:
assumes "prefs_from_rankings_wf xss" "prefs_from_rankings_wf yss"
assumes "map (index ys) S1 = S1'" "map (index ys) S2 = S2'"
assumes "inversion_number S1' = d1" "inversion_number S2' = d2"
assumes "d1 > d2 ∧ i < length agents_list ∧ ys = xss ! i ∧ yss = xss[i := zs]"
shows "swf' xss ≠ S1 ∨ swf' yss ≠ S2"
proof (rule ccontr)
assume *: "¬(swf' xss ≠ S1 ∨ swf' yss ≠ S2)"
with assms(1,2) have S12: "S1 ∈ permutations_of_set alts" "S2 ∈ permutations_of_set alts"
using swf'_wf by (auto simp: permutations_of_set_conv_mset)
have "ys ∈ set xss"
using assms card_agents by (auto simp: prefs_from_rankings_wf_def)
hence ys: "distinct ys" "set ys = alts"
using assms by (auto simp: prefs_from_rankings_wf_def list.pred_set mset_eq_alts_list_iff)
have d12: "swap_dist ys S1 = d1 ∧ swap_dist ys S2 = d2"
using assms(3-6) S12 ys
by (subst (1 2) swap_dist_conv_inversion_number) (simp_all add: permutations_of_set_def)
have "zs ∈ set yss"
using assms card_agents unfolding prefs_from_rankings_wf_def by (metis set_update_memI)
hence zs: "mset zs = mset_set alts"
using assms(2) by (auto simp: prefs_from_rankings_wf_def list.pred_set alts_list)
have "swap_dist ys (swf' xss) ≤ swap_dist ys (swf' yss)"
by (rule kemeny_strategyproof_swf'[where i = i]) (use zs assms card_agents alts_list in auto)
with * d12 assms show False
by simp
qed
end
locale majcons_weak_kstratproof_swf_explicit =
social_welfare_function_explicit agents alts swf agents_list alts_list +
majority_consistent_weak_kstratproof_swf agents alts swf
for agents :: "'agent set" and alts :: "'alt set" and swf agents_list alts_list
begin
sublocale majority_consistent_swf_explicit agents alts swf agents_list alts_list ..
lemma majority_consistent_kemeny_strategyproof_swf':
assumes "prefs_from_rankings_wf R1" "i < card agents" "mset zs = mset alts_list"
assumes "xs = R1 ! i" "majority_rel_mset (mset (R1[i := zs])) ys"
shows "swap_dist xs (swf' R1) ≤ swap_dist xs ys"
proof -
define R2 where "R2 = R1[i := zs]"
interpret res: finite_linorder_on alts "swf (prefs_from_rankings R1)"
by (intro swf_wf' prefs_from_rankings_wf_imp_is_pref_profile assms)
have R2_eq: "prefs_from_rankings R2 = (prefs_from_rankings R1)(agents_list ! i := of_ranking zs)"
unfolding ‹R2 = _› by (rule prefs_from_rankings_update) (use assms in auto)
have R2_wf: "prefs_from_rankings_wf R2"
unfolding ‹R2 = _› by (rule prefs_from_rankings_wf_update) (use assms in auto)
interpret R2: pref_profile_linorder_wf agents alts "prefs_from_rankings R2"
by (rule prefs_from_rankings_wf_imp_is_pref_profile) fact
interpret res': finite_linorder_on alts "swf (prefs_from_rankings R2)"
by (intro swf_wf' prefs_from_rankings_wf_imp_is_pref_profile R2_wf)
have "xs ∈ set R1"
using assms(1) ‹xs = R1 ! i› ‹i < _›
unfolding prefs_from_rankings_wf_def by auto
hence xs: "distinct xs" "set xs = alts"
using assms(1) by (auto simp: prefs_from_rankings_wf_def list.pred_set mset_eq_alts_list_iff)
have swf'_R1: "mset (swf' R1) = mset alts_list"
using assms(1) by (simp add: swf'_wf alts_list)
have swf'_R2: "mset (swf' R2) = mset alts_list"
using R2_wf by (simp add: swf'_wf alts_list)
have ys_eq: "majority (prefs_from_rankings R2) = of_ranking ys"
by (rule majority_prefs_from_rankings_eq_of_ranking) (use assms R2_wf in ‹auto simp: R2_def›)
have "mset ys = mset alts_list"
by (rule majority_rel_mset_imp_mset) (use R2_wf ‹majority_rel_mset _ _› in ‹auto simp: R2_def›)
have linorder_ys: "linorder_on alts (of_ranking ys)"
by (intro linorder_of_ranking) (use ‹mset ys = _› in ‹auto simp: mset_eq_alts_list_iff›)
have "swap_dist_relation (prefs_from_rankings R1 (agents_list ! i)) (swf (prefs_from_rankings R1)) ≤
swap_dist_relation (prefs_from_rankings R1 (agents_list ! i)) (majority (prefs_from_rankings R2))"
unfolding R2_eq
proof (rule majority_consistent_kemeny_strategyproof)
show "is_pref_profile (prefs_from_rankings R1)"
using assms(1) by auto
show "agents_list ! i ∈ agents"
using ‹i < _› card_agents by (metis agents_list finite_agents finite_set_mset_mset_set nth_mem_mset)
show "linorder_on alts (of_ranking zs)"
using ‹mset zs = _› alts_list finite_alts
by (metis finite_set_mset_mset_set linorder_of_ranking mset_eq_mset_set_imp_distinct set_mset_mset)
show "linorder_on alts (majority ((prefs_from_rankings R1) (agents_list ! i := of_ranking zs)))"
unfolding R2_eq [symmetric] ys_eq by (rule linorder_ys)
qed
also have "prefs_from_rankings R1 (agents_list ! i) = of_ranking (R1 ! i)"
by (rule prefs_from_rankings_nth) (use assms in auto)
also have "R1 ! i = xs"
using assms by simp
also have "swf (prefs_from_rankings R1) = of_ranking (ranking (swf (prefs_from_rankings R1)))"
by (simp add: res.of_ranking_ranking)
also have "… = of_ranking (swf' R1)"
by (simp add: swf'_def prefs_from_rankings_def)
also have "swap_dist_relation (of_ranking xs) (of_ranking (swf' R1)) = swap_dist xs (swf' R1)"
unfolding swap_dist_def using xs swf'_R1 by (auto simp: mset_eq_alts_list_iff)
also have "majority (prefs_from_rankings R2) = of_ranking ys"
by (rule ys_eq)
also have "swap_dist_relation (of_ranking xs) … = swap_dist xs ys"
unfolding swap_dist_def using xs swf'_R2 ‹mset ys = _› by (auto simp: mset_eq_alts_list_iff)
finally show ?thesis
using assms by simp
qed
end
end