with unchecked_deallocation; package body Sets_of_Unknowns is -- REPRESENTATION OF A SET : type Set_Rep is array (positive range <> ) of boolean; procedure free is new unchecked_deallocation(Set_Rep,Set); -- CREATORS : function Create ( n : natural ) return Set is s : Set := new Set_Rep'(1..n => false); begin return s; end Create; function Create ( s : Set ) return Set is s1 : Set; begin if s = null then s1 := s; else s1 := new Set_Rep'(s.all); end if; return s1; end Create; -- CONSTRUCTORS : procedure Add ( s : in out Set; i : in natural ) is begin s(i) := true; end Add; procedure Union ( s1 : in out Set; s2 : in Set ) is begin for i in 1..Dimension(s2) loop if Is_In(s2,i) then Add(s1,i); end if; end loop; end Union; function Union ( s1,s2 : Set ) return Set is s : Set := Create(s1); begin Union(s,s2); return s; end Union; procedure Remove ( s : in out Set; i : in natural ) is begin s(i) := false; end Remove; procedure Difference ( s1 : in out Set; s2 : in Set ) is begin for i in 1..Dimension(s2) loop if Is_In(s2,i) then Remove(s1,i); end if; end loop; end Difference; function Difference ( s1,s2 : Set ) return Set is s : Set := Create(s1); begin Difference(s,s2); return s; end Difference; procedure Intersection ( s1 : in out Set; s2 : in Set ) is begin for i in 1..Dimension(s1) loop if Is_In(s1,i) and then not Is_In(s2,i) then Remove(s1,i); end if; end loop; end Intersection; function Intersection ( s1,s2 : Set ) return Set is s : Set := Create(s1); begin Intersection(s,s2); return s; end Intersection; -- SELECTORS : function Dimension ( s : Set ) return natural is begin if s = null then return 0; else return s'last; end if; end Dimension; function Extent_Of ( s : Set ) return natural is cnt : natural := 0; begin for i in 1..Dimension(s) loop if Is_In(s,i) then cnt := cnt + 1; end if; end loop; return cnt; end Extent_Of; function Is_In ( s : Set; i : natural ) return boolean is begin return s(i); end Is_In; function Is_Subset ( s1,s2 : Set ) return boolean is begin for i in 1..Dimension(s1) loop if Is_In(s1,i) and then not Is_In(s2,i) then return false; end if; end loop; return true; end Is_Subset; function Is_Equal ( s1,s2 : Set ) return boolean is begin return (Is_Subset(s1,s2) and then Is_Subset(s2,s1)); end Is_Equal; procedure Generate_Subsets ( s : in Set; k : in positive ) is n : constant natural := Dimension(s); sub : Set := Create(n); cont : boolean; procedure Generate ( level,start : in natural ) is begin if level = 0 then Process(sub,cont); else for i in start..n-level+1 loop if Is_In(s,i) then Add(sub,i); Generate(level-1,i+1); Remove(sub,i); end if; exit when not cont; end loop; end if; end Generate; begin Generate(k,1); Clear(sub); end Generate_Subsets; procedure Generate_All_Subsets ( s : in Set ) is n : constant natural := Dimension(s); sub : Set := Create(n); cont : boolean; procedure Generate ( level,start : in natural ) is begin if level > 0 then for i in start..n loop if Is_In(s,i) then Add(sub,i); Process(sub,cont); if cont then Generate(level-1,i+1); Remove(sub,i); end if; end if; exit when not cont; end loop; end if; end Generate; begin Generate(n,1); Clear(sub); end Generate_All_Subsets; -- DESTRUCTOR : procedure Clear ( s : in out Set ) is begin free(s); end Clear; end Sets_of_Unknowns;