## warshall.a68

1 CO
2
3 @section Synopsis
4
5 Warshall's algorithm for transitive closures.
6
7 This code demonstrates a68g's small refinement preprocessor.
8 At the University of Nijmegen a preprocessor much like this one was used
9 as a front-end to FLACC in freshman programming courses in the 1980's.
10
11 See:
12
13 C.H.A. Koster, H. Meijer.
14 Systematisch programmeren in Algol 68, Deel I en II.
15 Kluwer, Deventer [1978, 1981].
16
17 CO
18
19 # Suppose a compiler finds four procedures that call each other
20 according below matrix.
21 Entry calls[j, k] means procedure 'j' calls 'k' directly.
22 #
23
24 INT n = 4;
25
26 MODE RELATION = [n, n] BOOL;
27
28 RELATION calls = ((FALSE, TRUE, FALSE, FALSE),
29 (FALSE, FALSE, TRUE, FALSE),
30 (FALSE, FALSE, FALSE, TRUE),
31 (FALSE, FALSE, FALSE, FALSE)
32 );
33
34 # Warshall's algorithm computes the transitive closure.
35 Entry warshall[j, k] means that 'j' calls 'k', either
36 directly or indirectly.
37 #
38
39 PROC warshall = (RELATION direct) RELATION:
40 (transitive closure);
41
42 print relations.
43
44 # The refinements follow below #
45
46 transitive closure:
47 RELATION indirect := direct;
48 construct indirect;
49 indirect.
50
51 construct indirect:
52 FOR m TO n
53 DO FOR s TO n
54 DO FOR t TO n
55 DO indirect[s, t] := indirect[s, t] OR (indirect[s, m] AND indirect[m, t])
56 OD
57 OD
58 OD.
59
60 print relations:
61 printf ($"direct:"l$);
62 printf (($n(n)(g)l$, calls));
63 printf ($"indirect:"l$);
64 printf (($n(n)(g)l$, warshall (calls))).