package body Bundles is procedure Transfer (This : in out Bundle; From, To : in Candidates.CandidateID; Excluded : in Candidates.Containers.CandidateID_Set; Value : in Rationals.Fraction; Result : out Bundle) is use type Candidates.CandidateID; Position : Positive; begin Result := Empty_Bundle; Result.Worth := This.Worth * Value; for P of This.Papers loop Position := Given_Prefs.Preference_Range'First; while Position <= Given_Prefs.Preference_Range'Last and then P (Position) /= From loop Position := Position + 1; end loop; Position := Position + 1; while Position <= Given_Prefs.Preference_Range'Last and then P (Position) /= Candidates.No_Candidate and then Excluded.Contains (P (Position)) loop Position := Position + 1; end loop; if Position <= Given_Prefs.Preference_Range'Last and then P (Position) = To then Result.Papers.Append (P); end if; end loop; end Transfer; function Count_Votes (This : in Bundle) return Natural is begin -- The number of votes under all normal circumstances should never exceed MAXINT return Natural (Rationals.Floor (Count_Papers (This) * This.Worth)); end Count_Votes; function Count_Papers (This : in Bundle) return Natural is begin return Integer (This.Papers.Length); end Count_Papers; procedure Count_Both (This : in Bundle; Votes : out Natural; Papers : out Natural) is begin Papers := Count_Papers (This); -- The number of votes under all normal circumstances should never exceed MAXINT Votes := Natural (Rationals.Floor (Papers * This.Worth)); end Count_Both; function "<" (Left, Right : in Bundle) return Boolean is begin return Left.Worth < Right.Worth; end "<"; end Bundles;