Skip to content

Rules

All rules expose a cowinners_ attribute. They are integrated via the rule_codes key in config/simulation.toml.

Rule codes

Main rules

Code Rule name Brief description
PLU1 Plurality Candidate with the most first-place votes wins
PLU2 Two-Round Plurality (Runoff) Top two candidates compete in a second-round runoff
HARE Hare / Instant-Runoff Voting Eliminate lowest candidates iteratively using ranked ballots
BUCK_R Bucklin Voting Selects candidate reaching majority at lowest rank level
BUCK_I Iterated Bucklin Repeated Bucklin elimination process
COPE Copeland's Method Score based on pairwise wins minus pairwise losses
SCHU Schulze Method Strongest path method on pairwise comparisons
MMIN Maximin (Minimax) Candidate with the strongest worst pairwise defeat wins
BLAC Black's Method Condorcet winner if one exists, otherwise Borda winner
KIMR Kim-Roush Each round, candidates with veto score strictly below average are simultaneously eliminated
WOOD Woodall's Method Perform IRV on the Smith set
YOUN Young's Method Elect the candidate who can become a Condorcet winner by removing the fewest voters
TIDE Tideman's Ranked Pairs Lock pairwise victories from strongest to weakest, avoiding cycles
BORD Borda Count Score candidates by ranked positions
COOM Coombs' Method IRV variant eliminating the most disliked candidate each round
NANS Nanson's Method Iterative elimination of candidates below the Borda average
BALD Baldwin's Method Iterative elimination of the lowest Borda score
MJ Majority Judgment Elect the candidate with the highest median grade
RV Range Voting Candidate with the highest average score wins
STAR STAR Voting Score then automatic runoff between the top two scored candidates
VETO Veto (Anti-Plurality) Candidate with the fewest last-place votes wins
AP_T0GE Approval Voting (utility ≥ 0) Approve all candidates with non-negative utility
AP_T05 … AP_T09 Approval Voting (threshold) Approve candidates above the given utility threshold (0.05, 0.06 … 0.9)
AP_K2 … AP_K12 K-Approval Approve a fixed number of top candidates (K = 2 … 12)
AP_KRP K-Approval (K = random Poisson) K drawn randomly from a Poisson distribution with λ = c/3
L1DV … L6DV Lp Distance Voting (p = 1 … 6) Weighted Lp-norm distance-based voting rules
DEPF Depth Function (default) Winner selection based on statistical data depth
DEPF_EXACT Depth Function (exact) Exact computation of the depth function winner
DEPF_GREEDY Depth Function (greedy) Greedy approximation of the depth function winner
DODG_C Dodgson's Method Minimum swaps needed for a candidate to become a Condorcet winner
DODG_S Dodgson's Method (score variant) Same, using the svvamp score-based implementation
COND Condorcet Weak Condorcet winner(s) elected; all tied otherwise
RANDOM_DICTATOR Random Dictator A random voter is picked and their top candidate is elected
RANDOM_WINNER Random Winner A random candidate is picked uniformly

Additional registered rules

These rules are also available in the registry but less commonly used.

Code Rule name
KEME Kemeny-Young — ⚠️ high computational cost
KEME_LAZY Kemeny-Young (lazy approximation)
SLAT Slater's Method — ⚠️ high computational cost
SPCY Split Cycle
RPAR Ranked Pairs
SIRV Smith-IRV
EXHB Exhaustive Ballot
ICRV ICRV
IRVA IRV Average
IRVD IRV Duels
CAIR Condorcet-Abs-IRV
CVIR Condorcet-Vtb-IRV
CSUM Condorcet Sum Defeats
APLU Approval (all candidates approved)
AP_T Approval Voting (threshold = 0.7, alias)
AP_K K-Approval (K = 2, alias)
AP_T05GE Approval Voting (utility ≥ 0.5)
AP_K_POISSON K-Approval (K = random Poisson, alias for AP_KRP)

How to add a rule

Use the public registry helpers to register custom rules:

from svvamp import RuleApproval

from vote_simulation.models.rules.registry import get_rule_builder, make_rule_builder, register_rule


register_rule(
    "AP_T8",
    make_rule_builder(lambda profile: RuleApproval(approval_threshold=0.8)(profile)),
)

ballots = [
    {"Alice": 1.0, "Bob": 0.9, "Chloe": 0.2},
    {"Alice": 0.85, "Bob": 0.7, "Chloe": 0.9},
]

result = get_rule_builder("AP_T8")(ballots)
print(result.cowinners_)

Rule index for mapping short codes to svvamp rule factories.

RuleResult

Bases: Protocol

Protocol for rule results that have been post-processed to include co-winners.

Source code in src/vote_simulation/models/rules/registry.py
class RuleResult(Protocol):
    """Protocol for rule results that have been post-processed to include co-winners."""

    cowinners_: list[str]

    def compute_metrics(self) -> Any: ...

get_all_rules_codes()

Return a list of all registered rule codes.

Source code in src/vote_simulation/models/rules/registry.py
def get_all_rules_codes() -> list[str]:
    """Return a list of all registered rule codes."""
    return sorted(_RULE_BUILDERS.keys())

get_rule_builder(code)

Return rule builder from code

Parameters:

Name Type Description Default
code str

rule encoding (detailed index in documentation)

required

Raises:

Type Description
ValueError

if wrong code

Returns:

Name Type Description
RuleBuilder RuleBuilder

rule applied

Source code in src/vote_simulation/models/rules/registry.py
def get_rule_builder(code: str) -> RuleBuilder:
    """Return rule builder from code

    Args:
        code (str): rule encoding (detailed index in documentation)

    Raises:
        ValueError: if wrong code

    Returns:
        RuleBuilder: rule applied
    """
    normalized_code = code.strip().upper()
    try:
        return _RULE_BUILDERS[normalized_code]
    except KeyError as error:
        available = ", ".join(sorted(_RULE_BUILDERS))
        raise ValueError(f"Unknown rule code: '{code}'. Available codes: {available}") from error

make_rule_builder(rule_factory)

Create a public RuleBuilder from a Profile -> rule result factory.

This helper is intended for external users who want to register custom rules while reusing the registry's profile conversion and co-winner post-processing.

Parameters:

Name Type Description Default
rule_factory Callable[[Profile], Any]

Callable that takes a svvamp.Profile and returns a rule result.

required

Returns:

Type Description
RuleBuilder

A RuleBuilder that can be registered in the registry.

Source code in src/vote_simulation/models/rules/registry.py
def make_rule_builder(rule_factory: Callable[[Profile], Any]) -> RuleBuilder:
    """Create a public `RuleBuilder` from a `Profile -> rule result` factory.

    This helper is intended for external users who want to register custom rules
    while reusing the registry's profile conversion and co-winner post-processing.

    Args:
        rule_factory: Callable that takes a `svvamp.Profile` and returns a rule result.

    Returns:
        A `RuleBuilder` that can be registered in the registry.
    """
    return _build_with_rule(rule_factory)

register_rule(code, builder)

Register a rule builder under a short code.

Source code in src/vote_simulation/models/rules/registry.py
def register_rule(code: str, builder: RuleBuilder) -> None:
    """Register a rule builder under a short code."""
    normalized_code = code.strip().upper()
    _RULE_BUILDERS[normalized_code] = builder