08-260
To: J3
From: Robert Corbett (via Michael Ingrassia)
Subject: J32031 : A semi-formal definition of type equivalence
Date: 2008 July 28
This is a follow-up to Public Comment J32031.
Section 4.5.2.4 of the draft Fortran 2008 standard and the
corresponding sections of the previous standards going back
to Fortran 90 is perhaps the most poorly written part of
the standard. It is incomplete and inconsistent. The
definition given for what it means for data entities to
have the same type allows for several different
interpretations. In Public Comment J32031 I [Bob]
gave the example
MODULE MOD
TYPE T1
SEQUENCE
INTEGER I
TYPE(T2), POINTER :: P
END TYPE
TYPE T2
SEQUENCE
INTEGER I
TYPE(T1), POINTER :: P
END TYPE
END
PROGRAM MAIN
USE MOD, ONLY: T3 => T1, T4 => T2
TYPE T1
SEQUENCE
INTEGER I
TYPE(T2), POINTER :: P
END TYPE
TYPE T2
SEQUENCE
INTEGER I
TYPE(T1), POINTER :: P
END TYPE
TYPE(T1) :: X
TYPE(T3) :: Y
Y%I = 1
NULLIFY(Y%P)
X = Y
END
In my comments, I said that a compiler from a major
vendor considered the variables X and Y to be of
different types and so gave an error for the
assignment X = Y, while other compilers considered
X and Y to be of the same type and so gave no error.
I pointed out that either interpretation is
consistent with the text of Section 4.5.2.4.
Other language specifications for languages that
define circular types to be equivalent if they are
structurally equivalent either define type
equivalence in terms of building a type graph and
then doing a search of the type graph or build
equivalence classes and then refine the equivalence
classes. Other specifications could be used, but I
have yet to find a language specification that uses
another approach.
I shall present a specification of type equivalence
based on refinement here. I do not expect the
committee to adopt my specification, but I hope it
might suggest ways to improve Section 4.5.2.4. My
specification is clumsier than it would be if I had
used standard mathematical notation instead of
restricting myself to using ASCII text.
A partition P of a set S is a set of subsets of S
such that
1) the null set is not an element of P,
2) the union of the sets in P is S, and
3) the intersection of any two distinct
sets in P is the null set.
The sets in P are equivalence classes.
A Fortran type t is a predefined type if and only if
1) t is one of the intrinsic types (2.5.1.1),
2) t is one of the five derived types
described in 14.2, or
3) t is one of the two derived types
described in 15.3.3.
For a given program, the program-defined types are
the derived types defined by derived-type definitions
that appear in the program.
Two Fortran types t and t' are inherently equivalent
if and only if t and t' are the same predefined type.
Let S be the set of derived-type definitions that
occur in a program and let P be a partition of S.
Two type t and t' are P-equivalent if and only if
1) t and t' are inherently equivalent, or
2) t and t' are both program-defined types,
t is declared with reference to a
derived-type definition d in S, t' is
declared with reference to a derived-type
definition d' in S, and d and d' are
elements of the same equivalence class
in P.
Let S be the set of derived-type definitions in a
program. Let P[1] be the partition of S such that
for any two distinct type definitions d and d' in S,
d and d' are in the same equivalence class in P[1]
if and only if
1) the type names of d and d' are the same,
2) the type name of d does not have the
PRIVATE attribute in the scoping unit in
which d appears, and the type name of d'
does not have the PRIVATE attribute in
the scoping unit in which d' appears,
3) d and d' have no components with PRIVATE
accessibility,
4) either d and d' both have the SEQUENCE
attribute or d and d' both have the BIND
attribute,
5) d and d' have the same number of type
parameters, and d and d' have the same
number of components,
6) the corresponding type parameters and
components of d and d' have the same
names,
7) the types of the corresponding type
parameters and components of d and d'
have the same number of type parameters.
8) the corresponding type parameter values
specified implicitly or explicitly for
the types of the corresponding type
parameters and components of d and d'
are equal, and
9) the attributes other than the types of
the corresponding type parameters and
components of d and d' agree.
Given the partition P[k] of S, k >= 1, the partition
P[k+1] is the partition of S such that for any two
derived-type definitions d and d' in S, d and d' are
in the same equivalence class in P[k+1] if and only
if d and d' are in the same equivalence class in P[k]
and the types of the corresponding type parameters
and components of d and d' are P[k]-equivalent.
Let n be the smallest positive integer such that
P[n] = P[n+1]. For any two types t and t', t and t'
are the same type if and only if t and t' are
P[n]-equivalent. If t and t' are not the same type,
they are different types.
As a regrettably simple example, consider the
application of the definition of type equivalence
to the example given at the start of this paper.
Let d[1] and d[2] denote the derived-type definitions
for T1 and T2 respectively in the module MOD, and let
d[3] and d[4] denote the derived-type definitions for
T1 and T2 respectively in the main program. Then S is
the set { d[1], d[2], d[3], d4] } and the partition
P[1] is the set { { d[1], d[3] }, { d[2], d[4] } }.
The types of the components named I in d[1] and d[3]
are inherently equivalent and so they are
P[1]-equivalent. The types of the components named
P in d[1] and d[3] are declared in reference to the
derived-type definitions d[2] and d[4] respectively.
Because d[2] and d[4] are in the same equivalence
class in P[1], the types of the components named P in
d[1] and d[3] are P[1]-equivalent. Therefore, the
equivalence class { d[1], d[3] } is a member of P[2].
Similarly, the types of the corresponding components
of d[2] and d[4] are P[1]-equivalent, and so the
equivalence class { d[2], d[4] } is a member of P[2].
Therefore, P[1] = P[2]. Therefore, the derived types
defined by d[1] and d[3] are the same type and the
types defined by d[2] and d[4] are the same types.
The derived type defined by d[1] is a different type
from the types defined by d[2] and d[4], and the
derived type defined by d[2] is a different type
from the type defined by d[1] and d[3].