ecclesia
Version:
Framework for political and electoral simulations
66 lines (65 loc) • 3.13 kB
TypeScript
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>>;