File : sets2.adb
package body Sets2 is
IPrim: constant Int := Int(Prim);
IPrim2: constant Int2 := Int2(Prim);
function Empty return S_Set is
begin
return Int(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
begin
return Int2(0);
end Empty;
function Full return L_Set is
begin
return not Int2(0);
end Full;
function Cardinality(S: L_Set) return Integer is
T: Int2 := 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: L_Element; S: L_Set) return Boolean is
begin
return S=(S or Int2(2**E));
end Contains;
procedure AddElement(E: in L_Element; S: in out L_Set) is
begin
S := S or Int2(2**E);
end AddElement;
procedure AddElements(S: in L_Set; T: in out L_Set) is
begin
T := T or S;
end AddElements;
procedure RmElement(E: in L_Element; S: in out L_Set) is
begin
S := S and not Int2(2**E);
end RmElement;
procedure FillGap(N: in Positive; S: in out L_Set) is
K: Integer := N;
T: L_Set := 1;
begin
loop
if (S and T)=Int2(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 L_Set; U: out IVec; ULast: out Integer) is
K: Integer := 0;
T: Int2 := 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: L_Set) return PMod is
begin
return PMod(S mod IPrim2);
end ModP;
begin
if L_Last>63 then raise Constraint_Error; end if;
end Sets2;