import { Counter } from "@gouvernathor/python/collections";
import { Election } from "../election";
import { Collection } from "@gouvernathor/python/collections/abc";
import { Vote } from "./vote";
import { DisagreementFunction } from "../election/voting";
/**
 * An electoral district relating to a House.
 *
 * Several district objects can represent the same territory and have the same
 * voter pool, but relate to different Houses : this is normal.
 * For example, the districts for the US state of Wyoming would be as follows:
 * - one for the three presidential electors
 * - one for the lone federal representative
 * - one or possibly two (depending on the implementation) for the two federal senators
 * All three or four of these districts would have the same voter pool, yet be
 * different objects because they relate to different Houses, even assuming
 * they have the same election method.
 */
export declare class District<Voter, Party> {
    electionMethod: Election<Voter, Party>;
    voters: Voter[];
    identifier?: string | number;
    nSeats?: number;
    constructor(electionMethod: Election<Voter, Party>, voters: Voter[], { identifier, nSeats }?: {
        identifier?: string | number;
        nSeats?: number;
    });
    election(candidates: Collection<Party>): Counter<Party, number>;
}
/**
 * A whole House of Parliament.
 * Some constraints:
 * - all members have the same voting power
 * - staggering is not supported - that is, when general elections don't
 *   renew all the seats at once, like in the french or US senates - though
 *   subclasses may implement it by overriding the election method and subclassing
 *   District, for instance.
 */
export declare class House<Voter, Party> {
    districts: Map<District<Voter, Party>, Counter<Party, number>>;
    name?: string;
    majority?: number;
    constructor(districts: Iterable<District<Voter, Party>> | Map<District<Voter, Party>, Counter<Party, number>>, { name, majority }?: {
        name?: string;
        majority?: number;
    });
    /**
     * Returns a Counter linking each party to the number of seats it holds,
     * regardless of the district.
     * For the array (with repetitions) of the individual members, use the
     * members.elements() method.
     */
    get members(): Counter<Party, number>;
    /**
     * If all districts support providing a theoretical number of seats,
     * returns the total. Otherwise, returns undefined.
     */
    get nSeats(): number | undefined;
    /**
     * Triggers an election in each electoral district, returns the members result.
     */
    election(candidates: Collection<Party>): Counter<Party, number>;
    /**
     * Returns the state of the vote on something having an opinion.
     * The object of the vote may be a motion or bill, but also a person to elect
     * or to confirm.
     */
    vote<T>(target: T, { disagree }: {
        disagree: DisagreementFunction<Party, T>;
    }): Vote;
}
