File : sets1.adb
package body Sets1 is
IPrim: constant Int := Int(Prim);
function Empty return S_Set is
begin
return 0;
end Empty;
function Full return S_Set is
begin
return not Int(0);
end Full;
function Cardinality(S: S_Set) return Integer is
T: Int := S;
N: Integer := Integer(T mod 2);
begin
while T /= 0 loop
T := T/2;
N := N+Integer(T mod 2);
end loop;
return N;
end Cardinality;
function Contains(E: S_Element; S: S_Set) return Boolean is
begin
return S=(S or Int(2**E));
end Contains;
procedure AddElement(E: in S_Element; S: in out S_Set) is
begin
S := S or Int(2**E);
end AddElement;
procedure AddElements(S: in S_Set; T: in out S_Set) is
begin
T := T or S;
end AddElements;
procedure RmElement(E: in S_Element; S: in out S_Set) is
begin
S := S and not Int(2**E);
end RmElement;
procedure FillGap(N: in Positive; S: in out S_Set) is
K: Integer := N;
T: S_Set := 1;
begin
loop
if (S and T)=Int(0) then
K := K-1;
if K=0 then S := (S or T); return; end if;
end if;
T := 2*T;
end loop;
end FillGap;
procedure UnPack(S: in S_Set; U: out IVec; ULast: out Integer) is
K: Integer := 0;
T: Int := S;
begin
ULast := -1;
loop
if (T mod 2) /= 0 then
ULast := ULast+1;
U(ULast) := K;
end if;
T := T/2;
exit when T=0;
K := K+1;
end loop;
end UnPack;
function ModP(S: S_Set) return PMod is
begin
return PMod(S mod IPrim);
end ModP;
function Empty return L_Set is
S: L_Set;
begin
for I in 0 .. ILast loop
S(I) := 0;
end loop;
return S;
end Empty;
function Full return L_Set is
S: L_Set;
begin
for I in 0 .. ILast loop
S(I) := not Int(0);
end loop;
return S;
end Full;
function Cardinality(S: L_Set) return Integer is
T: Int;
N: Integer := 0;
begin
for I in 0 .. ILast loop
T := S(I);
for K in 0 .. 31 loop
N := N+Integer(T mod 2);
T := T/2;
end loop;
end loop;
return N;
end Cardinality;
function Contains(E: L_Element; S: L_Set) return Boolean is
Si: constant Int := S(E/32);
begin
return Si=(Si or Int(2**(E mod 32)));
end Contains;
procedure AddElement(E: in L_Element; S: in out L_Set) is
I: constant Natural := E/32;
begin
S(I) := S(I) or Int(2**(E mod 32));
end AddElement;
procedure RmElement(E: in L_Element; S: in out L_Set) is
I: constant Natural := E/32;
begin
S(I) := S(I) and not Int(2**(E mod 32));
end RmElement;
procedure FillGap(N: in Positive; S: in out L_Set) is
K: Integer := N;
T: Int;
begin
for I in 0 .. ILast loop
T := 1;
declare
Si: constant Int := S(I);
begin
loop
if (Si and T)=Int(0) then
K := K-1;
if K=0 then S(I) := (Si or T); return; end if;
end if;
T := 2*T;
exit when T=Int(0);
end loop;
end;
end loop;
end FillGap;
function ModP(S: L_Set) return PMod is
Q: PMod := PMod(S(ILast) mod IPrim);
begin
for I in reverse 0 .. ILast-1 loop
Q := PFac*Q+PMod(S(I) mod IPrim);
end loop;
return Q;
end ModP;
end Sets1;