Skip to content

Commit c9d6256

Browse files
authored
Merge pull request #170 from wesholliday/main
Added Weak Single-Voter Resolvability
2 parents b9f6cf2 + 9eaa982 commit c9d6256

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

docs/source/variable_voter_axioms.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ Variable Voter Axioms
9999
100100
```
101101

102+
## Weak Single-Voter Resolvability
103+
104+
```{eval-rst}
105+
106+
.. autofunction:: pref_voting.variable_voter_axioms.has_weak_single_voter_resolvability_violation
107+
108+
.. autofunction:: pref_voting.variable_voter_axioms.find_all_single_voter_resolvability_violations
109+
110+
```
111+
102112
## Neutral Reversal
103113

104114
```{eval-rst}

pref_voting/variable_voter_axioms.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3349,6 +3349,8 @@ def find_all_participation_violations(prof, vm, verbose = False, violation_type
33493349

33503350
def has_single_voter_resolvability_violation(prof, vm, verbose=False):
33513351
"""
3352+
Single-Voter Resolvability requires that for any profile with multiple winners, each of the tied winners can be made the unique winner by adding a ballot (cf. Weak Single-Voter Resolvability, which only requires that at least one of the tied winners can be made the unique winner by adding a ballot).
3353+
33523354
If prof is a Profile, returns True if there are multiple vm winners in prof and for one such winner A, there is no linear ballot that can be added to prof to make A the unique winner.
33533355
33543356
If prof is a ProfileWithTies, returns True if there are multiple vm winners in prof and for one such winner A, there is no Ranking (allowing ties) that can be added to prof to make A the unique winner.
@@ -3481,6 +3483,79 @@ def find_all_single_voter_resolvability_violations(prof, vm, verbose=False):
34813483
find_all_violations = find_all_single_voter_resolvability_violations,
34823484
)
34833485

3486+
def has_weak_single_voter_resolvability_violation(prof, vm, verbose=False):
3487+
"""
3488+
Weak Single-Voter Resolvability requires that for any profile with multiple winners, at least one of the tied winners can be made the unique winner by adding a ballot (cf. Single-Voter Resolvability, which requires that each of the tied winners can be made the unique winner by adding a ballot).
3489+
3490+
If prof is a Profile, returns True if there are multiple vm winners in prof and for every such winner A, there is no linear ballot that can be added to prof to make A the unique winner.
3491+
3492+
If prof is a ProfileWithTies, returns True if there are multiple vm winners in prof and for every such winner A, there is no Ranking (allowing ties) that can be added to prof to make A the unique winner.
3493+
3494+
Args:
3495+
prof: a Profile or ProfileWithTies object.
3496+
vm (VotingMethod): A voting method to test.
3497+
verbose (bool, default=False): If a violation is found, display the violation.
3498+
3499+
Returns:
3500+
Result of the test (bool): Returns True if there is a violation and False otherwise.
3501+
"""
3502+
3503+
winners = vm(prof)
3504+
3505+
if isinstance(prof,ProfileWithTies):
3506+
prof.use_extended_strict_preference()
3507+
3508+
if len(winners) > 1:
3509+
3510+
for winner in winners:
3511+
3512+
found_voter_to_add = False
3513+
3514+
if isinstance(prof,Profile):
3515+
for r in permutations(prof.candidates):
3516+
new_prof = Profile(prof.rankings + [r])
3517+
if vm(new_prof) == [winner]:
3518+
found_voter_to_add = True
3519+
break
3520+
3521+
if isinstance(prof,ProfileWithTies):
3522+
for _r in weak_orders(prof.candidates):
3523+
r = Ranking(_r)
3524+
new_prof = ProfileWithTies(prof.rankings + [r], candidates = prof.candidates)
3525+
new_prof.use_extended_strict_preference()
3526+
if vm(new_prof) == [winner]:
3527+
found_voter_to_add = True
3528+
break
3529+
3530+
if found_voter_to_add:
3531+
return False
3532+
3533+
# If we get here, no tied winner can be made the unique winner by adding a ballot.
3534+
if verbose:
3535+
prof = prof.anonymize()
3536+
if isinstance(prof,Profile):
3537+
print(f"Violation of Weak Single-Voter Resolvability for {vm.name}: no tied winner can be made the unique winner by adding a linear ballot.")
3538+
if isinstance(prof,ProfileWithTies):
3539+
print(f"Violation of Weak Single-Voter Resolvability for {vm.name}: no tied winner can be made the unique winner by adding a Ranking.")
3540+
print("")
3541+
print("Profile:")
3542+
prof.display()
3543+
print(prof.description())
3544+
print("")
3545+
vm.display(prof)
3546+
prof.display_margin_graph()
3547+
print("")
3548+
3549+
return True
3550+
3551+
return False
3552+
3553+
weak_single_voter_resolvability = Axiom(
3554+
"Weak Single-Voter Resolvability",
3555+
has_violation = has_weak_single_voter_resolvability_violation,
3556+
find_all_violations = find_all_single_voter_resolvability_violations,
3557+
)
3558+
34843559
def has_neutral_reversal_violation(prof, vm, verbose=False):
34853560
"""Returns True if adding a reversal pair of voters (a voter with ranking L and a voter with the reverse ranking L^{-1}) changes the winners.
34863561

0 commit comments

Comments
 (0)