begin
   comment Test rig for fixed versions of CACM Algorithms 100 and 101;

   comment ALGORITHM 100 
     ADD ITEM TO CHAIN-LINKED LIST 
     PHILIP J. KIVIAT 
     United States Steel Corp., Appl. Research Lab., Monroeville, 
     Penn. ;
   procedure inlist(t, info, m, list, n, first, flag, addr, listfull);
      integer n, m, first, flag, t;
        integer array info, list, addr;
        label listfull;
        comment inlist adds the information pair {t,info} to the chain-
        link structured matrix list (i,j), where t is an order key >= 0, and
        info(k) an information vector associated with t. info(k) has
        dimension m, list(i,j) has dimensions (n * (m+3)). flag denotes
        the head and tail of list(i,j), and first contains the address of
        the first (lowest order) entry in list(i,j). addr(k) is a vector
        containing the addresses of available (empty) rows in list(i,j).
        Initialization: list(i,m+2) = flag, for some i <= n. If list(i,j) is
        filled exit is to listfull;
   begin
      integer i, j, k, link1, link2;
      L0:
      if addr[1]=0 then
        go to listfull
        else if addr[n] ≠ 0 then
      begin
         comment Insertion into an empty list;
         i ≔ flag;
         link1 ≔ m + 3;
         link2 ≔ m + 2;
         go to L3
      end;
      comment There is at least one element to compare against;
      i ≔ first;
      L1:
      if list[i, 1]⩽t then 
        begin
         comment Insert after first item - search forwards;
         link1 ≔ m+2;
         link2 ≔ m+3
      end
      else 
        begin
         comment Insert before first item - search backwards;
         link1 ≔ m+3;
         link2 ≔ m+2 
        end;

      if list[i, link2]≠flag then 
        begin
         comment Check the n̲e̲x̲t̲ element for the insertion point;
         k ≔ i;
         i ≔ list[i, link2];
         if(list[i, 1]>t)then
         begin
            comment Insertion point found;
            go to L4
         end
         else
         begin
            comment Continue the search;
            go to L1
         end
      end
      else 
        begin
         comment Insert a̲f̲t̲e̲r̲ i (depending on search direction).
           Link i into the new element;
         list[i, link2] ≔ addr[1]
      end;
      L3: ;
      comment Insert at one of the ends of the list,
        linking to element i in the opposite direction.
        As a special case, i = flag when inserting into the empty list;
      j ≔ addr[1];
      list[j, link1] ≔ i;
      list[j, link2] ≔ flag;
      if link2=m+2 then
        first ≔ addr[1];
      go to L5;
      L4: ;
      comment Insert between two existing elements;
      j ≔ addr[1];
      list[j, link1] ≔ list[i, link1];
      list[i, link1] ≔ list[k, link2] ≔ addr[1];
      list[j, link2] ≔ i;
      L5:
      list[j, 1] ≔ t;
      for i ≔ 1 step 1 until m do
           list[j, i+1] ≔ info[i];
      for i ≔ 1 step 1 until n-1 do
           addr[i] ≔ addr[i+1];
      addr[n] ≔ 0 
     end inlist ;

   comment ALGORITHM 101 
     REMOVE ITEM FROM CHAIN-LINKED LIST 
     PHILIP J. KIVIAT 
     United States Steel Corp., Appl. Res. Lab., Monroeville, 
     Penn. ;
   procedure outlist(vector, m, list, n, first, flag, addr);
      integer n, m, first, flag;
        integer array vector, list, addr;
        comment outlist removes the first. entry (information pair with 
        lowest order key) from list(i,j) and puts it in vector(k);
   begin
      integer i;
      for i ≔ 1 step 1 until m+1 do
           vector[i] ≔ list[first, i];
      comment Find the place to record release of the first entry;
      for i ≔ n, i - 1 while i > 1 ∧ addr[i] = 0 do
        ;
      if addr[i] = 0 then
        addr[i] ≔ first
      else
        addr[i+1] ≔ first;

      if list[first, m+3]=flag then 
        begin
         comment The list is now empty;
         list[1, m+2] ≔ flag
      end
      else 
        begin
         first ≔ list[first, m+3];
         list[first, m+2] ≔ flag 
        end
   end outlist ;

   procedure fill list (tvalues,info,m,list,n,first,flag,addr,listfull); 
        comment Fill list with sample data using Algorithm 100: inlist;
      integer n, m, first, flag;
        integer array addr, info, list, tvalues; 
        label listfull;

   begin
      integer i, j, t;

      for i ≔ 1 step 1 until n do
         begin
            comment set the key;
            t ≔ tvalues[i];
            comment set arbitrary values to be associated with the key;
            for j ≔ 1 step 1 until m do
               begin
                  info[j] ≔ 2×i + j
               end;
            outstrintnl(“Adding key ”, t);
            inlist(t, info, m, list, n, first, flag, addr, listfull);
            showlist(list, first, m, n, flag);
            checklist(list, first, m, n, flag, i);
            check free(addr, n, n - i)
         end
   end fill list;

   procedure showlist(list, first, m, n, flag);
      comment show the contents of the list, the end is
        assumed to be indicated by list[i, m+3] = flag;

      integer array list;
        integer first, m, n, flag;
   begin
      integer i, prev;
      outstring(1, “List contents: ”);
      i ≔ first;
      prev ≔ flag;
      next:
      if i = flag then go to endofproc;
      prev ≔ i;
      outinteger(1, list[i, 1]);
      i ≔ list[i, m+3];
      go to next;
      endofproc:
      outstring(1, “\n”)
   end showlist;

   procedure checklist(list, first, m, n, flag, list length);
      comment check that list is sorted from 1 ... list length
        and of the indicated length;
      integer array list;
        integer first, m, n, flag, list length;
   begin
      boolean error;

      error ≔ false;
      if first < 1 ∨ first > n then
      begin
         outstrintnl(“Invalid v̲a̲l̲u̲e̲ f̲o̲r̲ first: ”, first);
         error ≔ true
      end
      else
      begin
         integer checked, i, prev, t;

         comment dummy key for comparison at the start of the list;
         prev ≔ -1;
         i ≔ first;
         comment how many have been checked;
         checked ≔ 0;
         for checked ≔ checked + 1 while (checked ⩽ list length ∧ ¬error ∧ i ≠ flag) do
            begin
               t ≔ list[i, 1];
               if t < prev then
               begin
                  error ≔ true;
                  outstrint(“key ”, t);
                  outstrintnl(“out of order at position ”, i)
               end;
               prev ≔ t;
               comment follow the n̲e̲x̲t̲ link.;
               i ≔ list[i, m + 3]
            end;
         if checked ≠ list length + 1 then
         begin
            outstrint(“checking prematurely terminated after ”, checked - 1);
            outstrintnl(“rather than ”, list length)
         end
      end
   end checklist;

   procedure check free(addr, n, num free);
      comment check that addr has the correct number of free locations
        which should be equal to num free;
      integer array addr;
        integer n, num free;
   begin
      integer i, count;
      count ≔ 0;
      for i ≔ 1 step 1 until n do
           if addr[i] ≠ 0 then begin
            count ≔ count + 1
         end;
      if count ≠ num free then
      begin
         outstrint(“Incorrect number of free locations: ”, count);
         outstrintnl(“ which should be ”, num free)
      end
   end check free;

   procedure clear list(m, list, n, first, addr, list length);
      comment Clear the list sorted from 1 ... list length using
        Algorithm 101: outlist;
      integer array addr, list;
        integer first, m, n, list length;
   begin
      comment Variables for the outlist procedure;
      integer array vector[1:m + 1];

      integer i;

      outstring(1, “Clearing the list.\n”);
      for i ≔ 1 step 1 until list length do
         begin
            outlist(vector, m, list, n, first, flag, addr);
            check free(addr, n, i)
         end;
      if list[1, m+2] ≠ flag then
      begin
         outstrintnl(“list[1, m+2] has incorrect v̲a̲l̲u̲e̲ f̲o̲r̲ an empty list: ”, list[1, m+2])
      end
   end clear list;

   procedure outstrint(str, i);
      comment output str following by i;
      string str;
        integer i;
   begin
      outstring(1, str); outinteger(1, i)
   end outstrint;

   procedure outstrintnl(str, i);
      comment output str following by i and terminate with a newline;
      string str;
        integer i;
   begin
      outstrint(str, i);
      outstring(1, “\n”)
   end outstrintnl;

   comment Beginning of the test program;

   comment Variables for the inlist procedure;
   integer n, m, first, flag;
   comment info[1:m], list[1:n, 1:m+3], addr[1:n];
   comment 100 must be <= n, and 4 should be >= m;
   integer array info[1:4], list[1:100, 1:4+3], addr[1:100];

   comment Variables for the test procedure;
   integer i, j;
   comment 100 must be <= n;
   integer array tvalues[1:100];

   comment capacity of the list;
   n ≔ 4;
   comment amount of data associated with each key;
   m ≔ 4;
   comment index of the head item in list.
     first := -1;
   comment end-of-list marker;
   flag ≔ -1;

   comment set up the list of free locations;
   for i ≔ 1 step 1 until n do
      begin
         addr[i] ≔ i
      end;

   comment Set necessary initial terminating marker;
   list[1, m + 2] ≔ flag;

   comment Set up the tvalues to be used;
   tvalues[1] ≔ 7;
   tvalues[2] ≔ 13;
   tvalues[3] ≔ 6;
   tvalues[4] ≔ 11;

   if list[1, 2] ≠ 1 then
   begin
      comment The following is needed to avoid subscript error if list[1,2] != 0;
      list[1, m + 3] ≔ flag
   end;

   fill list(tvalues, info, m, list, n, first, flag, addr, listfull);

   comment try to fill the list beyond its capacity.
     This should fail with a jump to listfull;
   inlist(n + 1, info, m, list, n, first, flag, addr, listfull);
   outstring(1, “Failed t̲o̲ correctly detect attempt t̲o̲ add too many entries.\n”);
   go to testend;
   listfull:
   if i = (n+1) then
   begin
      outstrintnl(“List full correctly detected when attempting t̲o̲ add entry ”, i)
   end;
   testend:
   clear list(m, list, n, first, addr, n)
end