import { Counter } from '@gouvernathor/python/collections';
import { Collection } from '@gouvernathor/python/collections/abc';
import { Ballots } from './election/ballots.cjs';
import { Voting } from './election/voting.cjs';
import { Attribution } from './election/attribution/base.cjs';
import { RandomObjParam } from './utils.cjs';
import '@gouvernathor/rng';

/**
 * A function to go from a set of opinionated voters
 * to the elected representatives, the number of seats for each candidate.
 *
 * @param voters A pool of voters such as taken by the Voting functions.
 * @returns A multi-set (a Counter) of elected representatives as returned by an Attribution.
 */
interface Election<Voter, Party> {
    (voters: Collection<Voter>, candidates: Collection<Party>): Counter<Party>;
}
/**
 * Implements the most basic elections : combining a voting method and an attribution method.
 */
declare function standardElection<Voter, Party, B extends Ballots<Party>>({ votingMethod, attributionMethod }: {
    votingMethod: Voting<Voter, Party, B>;
    attributionMethod: Attribution<Party, B>;
}): Election<Voter, Party>;
/**
 * Implements a selection by lottery, directly among the population.
 * Adds the supplementary constraint that the voter type and the candidate type must be the same.
 *
 * The pool of candidates and the pool of citizens must be the same.
 * (Implementation detail : this is not enforced, and the pool of candidates is ignored.)
 * Returns elements from the pool picked without replacement,
 * so the pool must be at least nSeats in size.
 */
declare function sortition<Citizen>({ nSeats, ...randomParam }: {
    nSeats: number;
} & RandomObjParam): Election<Citizen, Citizen>;

export { type Election, sortition, standardElection };
