UNPKG

ecclesia

Version:

Framework for political and electoral simulations

66 lines (65 loc) 3.13 kB
import { Collection } from "@gouvernathor/python/collections/abc"; import { Approval, Ranked, Score, Single } from "./ballot"; export interface DisagreementFunction<T, U> { (t: T, u: U): number; } export interface VotingToBallot<Voter, Candidate, Ballot> { (voter: Voter, candidates: Collection<Candidate>): Ballot; } /** * The most basic and widespread voting system : * the voter chooses one of the available candidates, * or (not implemented here) for none of them. */ export declare function singleVote<Voter, Candidate>({ disagree }: { disagree: DisagreementFunction<Voter, Candidate>; }): VotingToBallot<Voter, Candidate, Single<Candidate>>; /** * The voter ranks all, or (not implemented here) some, of the candidates. */ export declare function orderingVote<Voter, Candidate>({ disagree }: { disagree: DisagreementFunction<Voter, Candidate>; }): VotingToBallot<Voter, Candidate, Ranked<Candidate>>; /** * The voter gives a score (or a grade) to each candidate. * The number of grades must be provided to the constructor. * * The implementation of this voting method is not as straightforward as the two previous ones, * even setting strategic voting aside. * What is to be considered to be the range of grades to cover ? * From nazis to angels, or from the worst present candidate to the best ? * The answer lies only in the minds of the voters. * The latter is more akin to orderingVote, so I implemented the former, * but it causes issues for lower grades so approvalVote uses the latter. * * In this implementation, the voter gives to each candidate * a score proportional to the raw disagreement. * This may yield situations where every party is graded 0, * especially with low nScores values. */ export declare function cardinalVote<Voter, Candidate>({ nScores, disagree }: { nScores: number; disagree: DisagreementFunction<Voter, Candidate>; }): VotingToBallot<Voter, Candidate, Score<Candidate>>; /** * Alternative implementation of cardinalVote. * The candidate(s) the least disagreed with are given the maximum score (which is nScores-1), * the candidate(s) the most disagreed with (unless all candidates have the same raw disagreement) gets 0, * and the score of the other candidates is proportional (well, affine) between those values. */ export declare function balancedCardinalVote<Voter, Candidate>({ nScores, disagree }: { nScores: number; disagree: DisagreementFunction<Voter, Candidate>; }): VotingToBallot<Voter, Candidate, Score<Candidate>>; /** * The voter approves or disapproves each of the candidates. * * Technically a special case of a cardinal/score vote where scores are 0 and 1, * but this one makes it open to additional attribution methods * (proportional ones for instance). * That's why the format it returns is not the same as with the cardinal vote. * If you want a scores-like ballot, use balancedCardinalVote({ nScores: 2 }) instead. */ export declare function approvalVote<Voter, Candidate>({ disagree }: { disagree: DisagreementFunction<Voter, Candidate>; }): VotingToBallot<Voter, Candidate, Approval<Candidate>>;