Annotation of 43BSDTahoe/ucb/pascal/tstpx/src/fay.p, revision 1.1.1.1

1.1       root        1: { AN OPEN CHALLENGE TO ALL PASCAL COMPILERS:  Compile this program
                      2:    correctly and produce the correct output. 
                      3: 
                      4:   Send responses, counter-challenges, etc., to:
                      5:    Tom Pennello
                      6:    Computer and Information Sciences
                      7:    University of California
                      8:    Santa Cruz, CA.  95064
                      9: }
                     10: 
                     11: program p(output);
                     12: type integer = -32767..32768; node = 0..4500;
                     13: var Debug: boolean;
                     14: 
                     15: procedure EachUSCC( { of relation R }
                     16:       { Pass in an iterator to generate the nodes to be searched,
                     17:         the relation on the nodes, a procedure to do information
                     18:         propagation when V R W is discovered, a procedure
                     19:         to take each SCC found, and a procedure to yield each
                     20:         node in the graph. 
                     21:         We require that the nodes be of a scalar type so that
                     22:         an array may be indexed by them.  Also passed in is the
                     23:         upper bound of the node type. }
                     24:       procedure EachUnode(procedure P(T:node)); { Yields each node in graph }
                     25:       procedure EachUnodeUtoUsearch(procedure SearchU(V:node));
                     26:       procedure R(V:node; procedure DoUsuccessor(W:node));
                     27:       procedure Propagate(V,W:node); { called when V R W is discovered }
                     28:       procedure TakeUSCC(Root:node; procedure Each(procedure P(T:node)));
                     29:       LastUnode: integer
                     30:       ); 
                     31: 
                     32:    type
                     33:       A = array[node] of integer; { range 0..Infinity (below) }
                     34:    var N: ^A;  SP: integer;
                     35:       Stack: array[node {1..LastUnode}] of node;
                     36:       Infinity: integer; { LastUnode+1 }
                     37: 
                     38:    procedure P(T:node); begin N^[T] := 0; end;
                     39:    
                     40:    procedure Search(V:node);
                     41:       var I,T:integer;
                     42:       procedure DoUsuccessor(W:node);
                     43:          begin
                     44:          Search(W);
                     45:          if N^[W] < N^[V] then N^[V] := N^[W];
                     46:          Propagate(V,W);
                     47:          end;
                     48: 
                     49:       { EachUmember is yielded by EachUSCC when an SCC has been found. }
                     50:       procedure EachUmember(procedure P(TU:node));
                     51:          var I:integer;
                     52:          begin { yield each member of current SCC }
                     53:          for I := SP downto T do P(Stack[I]);
                     54:          end;
                     55: 
                     56:       procedure YieldUSCC; 
                     57:          begin
                     58: if Debug then writeln('YieldUSCC passes',V,' to TakeUSCC');
                     59:          TakeUSCC(V,EachUmember);
                     60:          end; 
                     61: 
                     62:       begin
                     63:       if N^[V] = 0 then begin { stack the node }
                     64: if Debug then writeln('stacking ',V);
                     65:          SP := SP+1;
                     66:          Stack[SP] := V;  N^[V] := SP;
                     67: if Debug then writeln('Doing successors of ',V);
                     68:          R(V,DoUsuccessor);
                     69: if Debug then writeln('Now checking if ',V,' is an SCC root');
                     70:          if V = Stack[N^[V]] then begin { V is root of an SCC }
                     71:             T := N^[V];
                     72: if Debug then writeln(V,' is an SCC root; SP=',SP,' T=',T);
                     73:             for I := SP downto T do N^[Stack[I]] := Infinity;
                     74:             if SP <> T then begin
                     75: if Debug then writeln('Yield SCC should pass ',V,' out to TakeUSCC');
                     76:                YieldUSCC;
                     77:                end;
                     78:             SP := T-1;
                     79:             end;
                     80:          end;
                     81:       end; 
                     82:    begin
                     83:    Infinity := LastUnode+1;
                     84:    new(N); EachUnode(P);
                     85:    SP := 0;
                     86:    EachUnodeUtoUsearch(Search);
                     87:    dispose(N);
                     88:    end;
                     89: 
                     90: procedure Outer; { needed to produce bug in Berkeley Pascal compiler }
                     91:    procedure q;
                     92:       procedure EachUnodeUtoUsearch(procedure Search(T:node));
                     93:          begin 
                     94:          Search(1);
                     95:          end;
                     96:       procedure EachUnode(procedure P(T:node));
                     97:          begin P(1); P(2);
                     98:          end;
                     99:       procedure R(V:node; procedure P(W:node));
                    100:          begin 
                    101:          { Defines graph with edges 1->2 and 2->1 }
                    102:          { Thus, the graph contains one SCC:  [1,2] }
                    103:          case V of
                    104:             1: P(2); 
                    105:             2: P(1);
                    106:             end;
                    107:          end;
                    108:       procedure Propagate(V,W:node); begin end;
                    109:       procedure TakeUSCC(Root:node; procedure Each(procedure P(T:node)));
                    110:          procedure P(T:node); begin write(T); end;
                    111:          begin
                    112:          writeln('TakeUSCC receives V=',Root,' from YieldUSCC');
                    113:          writeln('The SCC''s constituents are:');
                    114:          Each(P); writeln;
                    115:          end;
                    116:       begin
                    117:       EachUSCC(EachUnode,EachUnodeUtoUsearch,R,Propagate,TakeUSCC,2);
                    118:       end;
                    119: 
                    120: procedure Doit;
                    121:    begin
                    122:    q;
                    123:    end;
                    124: 
                    125: begin
                    126: Doit;
                    127: end;
                    128: 
                    129: begin
                    130: Debug := true;
                    131: Outer;
                    132: end.
                    133: 
                    134: {----------------------------------------------------------------
                    135:   An alternate version of this program, written in a language 
                    136:   supporting iterators, iterators as parameters, iterators
                    137:   as yielded results of iterators, and the ability to yield more
                    138:   than one thing, might be as follows:
                    139:  ----------------------------------------------------------------
                    140: 
                    141: iterator EachUSCC(
                    142:    iterator EachUnode:node;
                    143:    iterator EachUnodeUtoUsearch:node;
                    144:    iterator R(V:node):node;
                    145:    procedure Propagate(V,W:node);
                    146:    LastUnode:node
                    147:                  ):
                    148:    (Root:node; iterator EachUnodeUinUSCC:node);
                    149:    # EachUSCC yields two results:  the Root of the SCC,
                    150:    # and an iterator that yields each member of that SCC.
                    151: 
                    152:    type A = aray[node] of integer;
                    153:    var N: ^A; SP: integer;
                    154:        Stack: array[node] of node;
                    155:        Infinity: integer;
                    156:  
                    157:    procedure Search(V);
                    158:       var T: integer;
                    159:       iterator EachUmember:node;
                    160:          begin
                    161:          for I := SP downto T do P(Stack[I]);
                    162:          end;
                    163:       begin
                    164:       if N^[V] = 0 then begin
                    165:          SP := SP+1;  Stack[SP] := V;  N^[V] := SP;
                    166:          for W in R(V) do begin   # Search successors of V.
                    167:             Search(W);
                    168:             if N^[W] < N^[V] then N^[V] := N^[W];
                    169:             Propagate(V,W);
                    170:             end;
                    171:          if V = Stack[N^[V]] then begin 
                    172:             T := N^[V];           # V is an SCC root.
                    173:             for I := SP downto T do N^[Stack[I]] := Infinity;
                    174:             if SP <> T then       # Non-trivial SCC.
                    175:                yield(V,EachUmember);
                    176:             SP := T-1;
                    177:             end;
                    178:          end;
                    179:       end;
                    180: 
                    181:    begin
                    182:    Infinity := LastUnode+1;
                    183:    new(N);
                    184:    for T in EachUnode() do N^[T] := 0;  # for loops declare their
                    185:    SP := 0;                             # control variable as a constant.
                    186:    for V in EachUnodeUtoUsearch() do Search(V);
                    187:    dispose(N);
                    188:    end;
                    189: 
                    190: # Sample use of EachUSCC:
                    191: 
                    192: iterator EachUnodeUtoUsearch:node;
                    193:    begin 
                    194:    yield(1);
                    195:    end;
                    196: iterator EachUnode:node;
                    197:    begin
                    198:    yield(1); yield(2);
                    199:    end;
                    200: iterator R(V:node):node;
                    201:    begin
                    202:    if V = 1 then yield(2) else yield(1);
                    203:    end;
                    204: procedure Propagate(V,W:node); begin end;
                    205: 
                    206: procedure UseUEachUSCC;
                    207:    begin
                    208:    for (Root,EachUmember) in 
                    209:        EachUSCC(EachUnode,EachUnodeUtoUsearch,R,Propagate,TakeUSCC,2) do
                    210:       begin
                    211:       writeln('Root of received SCC is ',Root);
                    212:       writeln('Constituents of the SCC are:');
                    213:       for I in EachUmember() do write(I);
                    214:       writeln;
                    215:       end;
                    216:    end;
                    217: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.