In Fortran IV, how are arrays assigned by a single value, and how are some goto operations handled?

106 views Asked by At

I have a semantic problem with a very old Fortran IV (Fortran 66) program. This leads to 2 questions.

Context

The program should calculate the Ackermann function in O(1) memory. It comes from here: The old paper.

It is a paper written by Henry Gordon Rice (Gordon Rice, the wiki page stipulates that he wrote the above paper). Why reading such an old paper? For fun and as a reScience test.

This is the original code:

 1    INTEGER FUNCTION ACKER(M,N)
 C    Size of VALUE and PLACE tables is one more than LARGEST M EXPECTED (else too long computation)
 2      INTEGER VALUE(6), PLACE(6)
 C    Test ofr Zero M
 3      IF (M .NE. O) GO TO 6
 4      ACKER = N+l
 5      RETURN
 C   Non Zero M INITIALIZE FOR ITERATION
 6      VALUE = 1
 7      PLACE = 0
 C      ITERATION LOOP. GET NEW VALUE.
 8      VALUE = VALUE + 1
 9      PLACE = PLACE + 1
 10     DO 18 I=1,M
 11         IF (PLACE(I) .NE. 1) GO TO 16
 C          INITIATE NEW LEVEL
 12         VALUE(I+1) = VALUE
 13         PLACE(I+1) = 0
 14         IF (I .EQ. M) GO TO 18
 15         GO TO 8
 16         IF (PLACE(I) .NE. VALUE(I+1) GO TO 8
 17         VALUE(I+1) = VALUE
 18         PLACE(I+1)=PLACE(I+1)+1
 C     CHECK FOR END OF ITERATION
 19     IF (PLACE(M+1) .NE. N) GO TO 8
 20     ACKER = VALUE
 21     RETURN
 22  END

The code again without comments:

 1   INTEGER FUNCTION ACKER(M,N)
 2      INTEGER VALUE(6), PLACE(6)
 3      IF (M .NE. O) GO TO 6
 4      ACKER = N+l
 5      RETURN
 6      VALUE = 1
 7      PLACE = 0
 8      VALUE = VALUE + 1
 9      PLACE = PLACE + 1
 10     DO 18 I=1,M
 11         IF (PLACE(I) .NE. 1) GO TO 16
 12         VALUE(I+1) = VALUE
 13         PLACE(I+1) = 0
 14         IF (I .EQ. M) GO TO 18
 15         GO TO 8
 16         IF (PLACE(I) .NE. VALUE(I+1) GO TO 8
 17         VALUE(I+1) = VALUE
 18         PLACE(I+1)=PLACE(I+1)+1
 19     IF (PLACE(M+1) .NE. N) GO TO 8
 20     ACKER = VALUE
 21     RETURN
 22  END

It is a very short program compared to most iterative ones:

Problem

So, when reading the code, to understand how it works, 2 things troubled me:

  1. If PLACE is an array/table, how works the assignment PLACE=1 ? 1 everywhere ? 1 to the first cell ? PLACE is also a kind of hidden index ?
    It is the same question about PLACE = PLACE + 1. How it works ? (recall PLACE is not an integer variable but an array)

  2. Some GOTOs inside the DO-LOOP (a kind of for-loop) go away from the range (body) of the do-loop. And then the code can re-enter the range/body of the the do-loop. If so, is the variable J reset? Or is a copy used (so there would be a hidden stack?).

Some references about the Fortran IV versions: Fortran IV Programmer's Reference Manual

I tried to convert the code to Java, but without an understanding of the semantics, I can't. I tried to compile it with "g77 -ff66" without success. And I tried reading papers about Fortran IV and iterative algorithms for the Ackermann function.

Hint: I am absolutely not a Fortran programer.

1

There are 1 answers

10
PierU On

Part 1)

Assigning or using a whole array at once is a so-called "array syntax", which was introduced only in Fortran 90. AFAIK, something like PLACE = 0 was illegal in Fortran 66 or 77. So there are two hypothesis here:

  • the code was relying on a non-standard and non-portable behavior of some compiler(s) at that times, such as PLACE was (maybe) a shortcut for PLACE(1)
  • someone modified the original code to take advantage of the F90 array syntax

But the latter hypothesis is unlikely, because the code also contains things like VALUE(I+1) = VALUE, which the assignment of a whole array to a scalar element: this is illegal in all Fortran standards, old or recent.

Part 2)

Escaping from a do-loop with a goto statement was fine (and before Fortran 90 it was the only way). In your example, when entering again the do-loop, the J variable is simply reset to the initial value of the loop, and there's no new instance of this variable.

What is/was not authorized is jumping inside a do-loop with a goto statement that is outside the loop.

Edit

Here is, I think, the right version of the code.

  • I replaced all unindexed array references by references to the first element
  • I fixed some wrong indentations (this is the old-school fixed-source format, where statements had to start at column 7)
  • I added a missing parenthesis on the line labelled "11"
  • I replaced the GO TO 18 by GO TO 19 on the line labelled "14"
 1      INTEGER FUNCTION ACKER(M,N)
 2      INTEGER VALUE(6), PLACE(6)
 3      IF (M .NE. O) GO TO 6
 4      ACKER = N+l
 5      RETURN
 6      VALUE(1) = 1
 7      PLACE(1) = 0
 8      VALUE(1) = VALUE(1) + 1
 9      PLACE(1) = PLACE(1) + 1
 10     DO 18 I=1,M
 11         IF (PLACE(I) .NE. 1) GO TO 16
 12         VALUE(I+1) = VALUE(1)
 13         PLACE(I+1) = 0
 14         IF (I .EQ. M) GO TO 19
 15         GO TO 8
 16         IF (PLACE(I) .NE. VALUE(I+1)) GO TO 8
 17         VALUE(I+1) = VALUE(1)
 18         PLACE(I+1)=PLACE(I+1)+1
 19     IF (PLACE(M+1) .NE. N) GO TO 8
 20     ACKER = VALUE(1)
 21     RETURN
 22     END