-- integer set (linked list in decreasing order) by R J Botting, CSUSB with Text_io; use Text_io; package body INTEGER_SETS is -- The elements are kept in decreasing order with no duplicates -- For all S, S=empty or S.first>S.rest.first>S.rest.rest.first>... -- by R J Botting, CSUSB -- INTEGER_SET is access DATA and NULL_SET=INTEGER_SET(NULL). -- In this package "=" is often the Package's own "=" operation! package IIO is new Text_IO.Integer_io(integer); --need integer output use iio; type DATA is record FIRST:INTEGER; REST:INTEGER_SET:=NULL; end record; function Empty(ISIN:INTEGER_SET) return boolean is DUMMY:INTEGER; begin --notice that we can NOT use `ISIN=NULL` since this uses "=". DUMMY:=ISIN.FIRST; --exception if empty return false; exception when CONSTRAINT_ERROR=>return true; end Empty; function EQ(I:INTEGER; T:INTEGER_SET) return boolean is -- T.first exists and equals I begin return not Empty(T) and then T.FIRST=I; end EQ; function FIND(I:INTEGER; S:INTEGER_SET) return INTEGER_SET is --find position in S, just before place for I T1: INTEGER_SET; T2: INTEGER_SET; begin --AFTER: if Empty(S) then T1=NULL -- if S={J} then T1=(FIRST=>J, rest=>NULL) -- else T1/=NULL/=T1.rest and -- T1.FIRST > I >= T1.rest.FIRST T1:=S; T2:=T1; while not Empty(T2) and then I=T2.rest.first and II, REST=>null); elsif INTO.FIRST = I then null; -- I is already in the set elsif INTO.FIRST < I then -- I belongs at the start of the set INTO:=new DATA'(FIRST=>I, REST=>INTO); else -- need to find T1 before place for I T1:=INTO; T1:=FIND(I,T1); T2:=T1.REST; if not EQ(I,T2) then T1.REST:=new DATA'(FIRST=>I, REST=>T2); end if; end if; end; procedure Take(I:INTEGER; FROM:in out INTEGER_SET) is T1,T2:INTEGER_SET; begin if Empty(FROM) then null; elsif FROM.FIRST=I then FROM:=INTEGER_SET(FROM.REST); else T1:=FROM; T2:=T1.REST; while not Empty(T2) and then I