last changed 10/19/2025
TODO review/bring up to date
enum class SocialChoiceFunction { PLURALITY, APPROVAL, SUPERMAJORITY, IRV }
class ContestInfo(
val name: String,
val id: Int,
val candidateNames: Map<String, Int>, // candidate name -> candidate id
val choiceFunction: SocialChoiceFunction, // electionguard has "VoteVariationType"
val nwinners: Int = 1, // aka "numberElected"
val voteForN: Int = nwinners, // aka "contestSelectionLimit" or "optionSelectionLimit"
val minFraction: Double? = null, // supermajority only.
)
- over all contests, verify that the contest names and ids are unique.
class Contest(
val info: ContestInfo,
val votes: Map<Int, Int>, // candidateId -> nvotes
val Nc: Int, // trusted maximum ballots/cards that contain this contest
val Ncast: Int, // number of cast ballots containing this Contest, including undervotes
val winners: List<Int>,
)
class IrvContest(
val info: ContestInfo,
val winners: List<Int>, // actually only one winner is allowed
val Nc: Int,
val Ncast: Int,
val undervotes: Int,
)
class DHondtContest(
info: ContestInfo,
voteInput: Map<Int, Int>,
Nc: Int, // trusted maximum ballots/cards that contain this contest
Ncast: Int, // number of cast ballots containing this Contest, including undervotes
val sortedScores: List<DhondtScore>,
): Contest(info, voteInput, Nc, Ncast)
- verify that the candidateIds match whats in the ContestInfo
- verify that the candidateIds are unique
- verify that nwinners == min(ncandidates, info.nwinners)
- if non-IRV, verify that the winners have more votes than the losers (margins > 0 for all assertions)
- if non-IRV, check that the top nwinners are in the list of winners
data class AuditableCard (
val location: String, // info to find the card for a manual audit. Aka ballot identifier.
val index: Int, // index into the original, canonical list of cards
val prn: Long, // psuedo random number
val phantom: Boolean,
val contests: IntArray, // list of contests on this ballot. optional when !hasStyle
val votes: List<IntArray>?, // for each contest, an array of the candidate ids voted for; for IRV, ranked first to last; missing for pooled data
val poolId: Int?, // for OneAudit
)
- Check that all card locations and indices are unique, and the card prns are in ascending order
- Given the seed and the PRNG, check that the PRNs are correct and are assigned sequentially by index.
- Check that the count of phantom cards containing a contest = Contest.Nc - Contest.Ncast.
data class Cvr(
val id: String, // ballot identifier
val votes: Map<Int, IntArray>, // contest -> list of candidates voted for; for IRV, ranked first to last
val phantom: Boolean = false,
val poolId: Int? = null,
)
- Check that each CVR has a corresponding AuditableCard, where id = location
For non-IRV contests:
- CLCA: tabulate the cvrs and check totals agree with Contest votes
- OneAudit: tabulate the cvrs and the pool votes and check totals agree with Contest votes
For IRV contests:
- CLCA: tabulate the cvrs and check VoteConsolidations agree with RaireContest
- Polling and OneAudit not currently possible
For each audit round, for each contest, verify that the cards selected for auditing have the smallest PRN.
- if !hasStyle the cards are selected using UniformSampling.
- if hasStyle the cards are selected using ConsistentSampling.