(chibi voting)

Preferential voting utilities to help come to reasonable decisions when there are more than 2 options. Currently we provide 3 common voting implementations, with batch and incremental tallying. In this library, a candidate is a non-numeric object compared via eq? such as a symbol and a tally is an object aggregating votes. A single vote is a list of lists of candidates in order of preference. The inner lists may have multiple elements to represent an equal preference among the options, so that the vote ((A B) (C)) represents a preference of either A or B equally over C. A vote should not have any duplicate candidates, but need not include all eligible candidates.

Ranking

(tideman-rank x)

Aka "ranked pairs" voting, returns a list of candidates ordered by the largest pairwise preference above other candidates. x should be either a tally or alist of votes. Unlike plurality-rank and instant-runoff-rank satisfies the Condorcet winner and loser criteria, the Smith criterion, and various other criteria desirable in motivating people to vote honestly and without strategy for their actual preferences. Recommended for most use cases.

(plurality-rank x)

Aka "first-past-the-post" voting, returns a list of candidates ordered by their frequency as the first place vote. This is the voting used in most elections. x, which can be either a tally or alist of votes. The keys of the alist should be some identifier of the voter, but are for debugging purposes and not actually used. Second or later preferences are allowed but ignored by the algorithm. However, unlike traditional plurality voting, each vote may have multiple first place choice candidates which are counted equally. If equal weighted votes are not desired they should be filtered separately prior to tallying.

(instant-runoff-rank x)

Aka "IRV" or "ranked-choice voting" (RCV), returns a list of candidates ordered by successive rounds of removing the last place candidate. This is the system used in most of Australia's elections among other uses, and as such is perhaps the best known preferential voting system. However, it fails to satisfy the Condorcet winner criteria, which is to say that even if there is a candidate preferred pairwise over all other candidates, they may not necessarily win. x should be either a tally or alist of votes. Unlike traditional IRV this implementation allows equal weighted votes which should be filtered prior to tallying if undesired.

Tallying

A Tally is an object holding an aggregated count of preferential votes. On creation you specify what level of aggregation is done. The most general case is distinct, which keeps a count of each unique preferential vote. The next most general is pairwise, which counts just pairwise preferences, followed by the default which just counts the number of times a candidate appeared as the first choice.

(make-tally . args)

Returns a tally of candidate first place counts. candidates should be a vector of all valid candidates.

(make-paired-tally . args)

Returns a tally of candidate vs candidate pairwise counts.

(make-distinct-tally . args)

Returns a tally of counts of each distinct preferential vote, in addition to pairwise and first place counts.

(tally-distinct-ref tally vote)

(tally-pairwise-ref tally i j)

(tally-inc! tally vote [count])

Add a new vote to the tally.Returns a tally for the votes alist votes.

(votes->paired-tally votes [candidates])

Returns a tally with pairwise aggregation for the votes alist votes.Returns a tally with distinct aggregation for the votes alist votes.

(tally->distinct-alist tally)

Returns an alist of distinct vote to count for the given tally.

(distinct-alist->tally ls)

Returns a new tally with distinct aggregation for the given vote to count alist.

(tally->pairs tally)

Returns an alist with (candidate . candidate) pair keys and count values for the given tally.

(pairs->tally pairs [count])

Returns a new tally with pairwise aggregation for the given alist of pairs having (candidate . candidate) keys and count values.

(sort-pairs x)

(lock-pairs pairs)