Uniqueness Typing in Natural Deduction Style

We present two type systems for graph rewriting: conventional typing and (polymorphic) uniqueness typing. The latter is introduced as a natural extension of simple algebraic and higher-order uniqueness typing. The systems are given in natural deduction style using an inductive syntax of graph denotations with familiar constructs such as let and case. 
 
The conventional system resembles traditional Curry-style typing systems in functional programming languages. Uniqueness typing extends this with reference count information. In both type systems, typing is preserved during evaluation, and types can be determined effectively. 
 
Due to the present formalization, the system can easily be compared with other proposals based on linear and affine logic.


Introduction
In recent years, various proposals have been brought up to capture the notion of assignment in a functional context. This desire is paradoxical, because the absence of side e ects is one of the main reasons why functional programming languages are often praised. As a consequence of this absence, functional languages have the fundamental property of referential transparency: each (sub)expression denotes a xed value, independently of the way this value is computed.
We regard assignments in a broad sense: these include direct mutation of memory contents but also more indirect I/O operations like le manipulations. The common aspect of such operations is their destructive behaviour: they (irreversibly) change the state of their input objects.
There is a solution for this problem which can be achieved entirely within the functional framework: by delivering a sequence of instructions for the operating system as a result of a functional expression. One could call this a delegating approach, since the computation only prepares for the external execution of, for example, I/O tasks. In the literature, this method is known as stream based I/O. An application can be found in the language Haskell.
Rather than this indirect treatment of destructive operations one would like to incorporate them (and hence the objects they operate on) directly in a functional programming language. This admits a more re ned control of les, for example. However, by admitting these operations without precaution one loses referential transparency. If two destructive functions operate on the same le, for example, the result of the program depends on the order in which these operations are performed.
The problem is, therefore, to identify suitable restrictions on the usage of destructive operations. The essence of recent solutions (e.g., Wadler (1990), Guzm an and Hudak (1990)) is to restrict destructive operations to arguments that are accessed only once. Syntactically, this boils down to retricting the number of occurrences of these arguments inside each program to one. The uniqueness type system for graph rewrite systems presented in Barendsen and Smetsers (1993). o ers the possibility to indicate such reference count requirements in type speci cations of functions. This is done via so-called uniqueness types which are annotated versions of traditional Curry-like types. E.g. the operation WriteChar which writes a character to a le is typed with WriteChar : (Char ; File ) ! File . Here, ; stand for`unique' (the requirement that the reference count is 1) and`non-unique' (no reference requirements) respectively.
Uniqueness typing can be regarded as a combination of linear typing (dealing with unique objects) and traditional typing (for non-unique objects), connected by a subtyping mechanism. In fact, the part handling uniqueness allows discarding of objects, so it corresponds more closely to a ne logic, see Blass (1992). A logical/categorical proposal for a related combination appears in Benton (1994).
The present paper describes the uniqueness type system in natural deduction style, using an inductive syntax for graph expressions. The emphasis on graph denotations contrasts the original presentation, which referred directly to the node/reference structure of (non-inductive) graph objects. The graph syntax is similar to the object language in the equational approach towards Term Graph Rewriting of Ariola and Klop (1995). The operational semantics of the object language is given by the concept of Term Graph Rewriting, as introduced by Barendregt et al. (1987). Each expression is translated into a term graph. In contrast with Ariola and Klop (1995), we refrain from de ning a reduction relation on the expressions directly.
The paper is organized as follows. After a very short and informal introduction to Term Graph Rewriting (Section 2), we introduce a formal language for denoting graph expressions and function de nitions (Section 3). Section 4 describes the incorporation of higher-order functions in our system. In Section 5 a Curry style (conventional) type system is introduced. The system is not new, but the terminology and techniques in this section prepare for the development of uniqueness typing, which will proceed along the same lines. We prove preservation of typing during reduction and the existence of principal types. After an informal introduction to uniqueness typing in Section 6, Section 7 describes a simple (i.e., non-polymorphic) algebraic uniqueness type assignment system. This system is extended via higher-order typing to the complete polymorphic uniqueness type system (Section 8). The results for the conventional system are extended to uniqueness typing. At the end of Section 8 we describe how uniqueness type inference proceeds in the functional programming language Clean (see also Plasmeijer and van Eekelen (1995). We conclude with a discussion of related work and future research (Section 9).
The original uniqueness type system is rather complex, particularly due to the re ned reference analysis. To avoid that the reader gets entangled in technical details, this analysis is kept here as simple as possible: it does not take the evaluation order into account. Due to the present formalization, the system can easily be compared with other proposals based on linear and a ne logic.
This paper is an elaborated version of the work presented in Barendsen and Smetsers (1995a) and Barendsen and Smetsers (1995c).

Term graph rewriting
Term graph rewrite systems (TGRS's) have been introduced in Barendregt et al. (1987), see also Barendsen and Smetsers (1994). This section summarizes some basic concepts.
Term graph rewriting can be seen as an extension of term rewriting with sharing. In term rewrite rules, multiple occurrences of variables lead to duplication of actual instances. In TGRS's, such duplications are avoided by copying references to the objects instead of copying the objects themselves.
The objects in TGRS's are directed graphs in which each node is labelled with a symbol. Each symbol S, say, has a xed arity determining the number of outgoing edges (references to the arguments) of any node labelled with S.
We distinguish two kinds of symbols: function symbols and algebraic constructor symbols. Function symbols are introduced by rewrite rules which specify transformations of graphs. Each rewrite rule Fp ! g consists of left-hand side Fp (the pattern) and a right-hand side g (the result). Both Fp and g are graphs. We say that a rule is left-linear if the pattern Fp is a tree (hencep does not contain multiple occurrences of the same variable). This enables us to denote left-hand sides of rewrite rules as terms. We consider function/constructor rules:p contains only variables and algebraic constructors.
The following picture shows a graph rewrite step according to the displayed rule.

Graph denotations Syntax
In order to present our type systems in natural deduction style, we introduce graph denotations generated by an inductive syntax. The language constructs re ect the essential aspects of graph rewriting: application, sharing (implicitly, by multiple occurrences of the same variable, and explicitly, using let), cycles (sharing using letrec), pattern matching (case), and function de nitions.
Instead of admitting several rules (one for each alternative pattern) for functions, we collect all alternatives in a case construct.
De nition 3.1 (i) The objects are expressions generated by the following abstract syntax. E ::= x j S(E1; : : : ; E k ) j let x = E in E 0 j letrecx =Ẽ in E 0 j case E ofPjẼ; P ::= C(x1; : : : ; xk): Here x;x range over (sequences of) term variables, and S over some set of symbols of xed arity (we will suggestively use F for functions and C for data constructors). The set of free variables of E (notation FV(E)) is de ned as usual.
(ii) Function de nitions are expressions of the form F(x 1 ; : : : ; x k ) = E: Some hygiene with respect to variables is necessary: in let x = E in E 0 , the variable x should not occur free in E. We only consider left-linear functions: no variable occurs more than once in the same pattern. Moreover, these pattern variables are`local': they occur only inP jẼ. Example 3.2 (i) The expression let x = 0 in letrec z = F(Cons(x; G(x; z))) in z denotes the following graph. Add(x; y) = case x of 0 j y S(x 0 ) j S(Add(x 0 ; y)):

Semantics
We now give a formal account of the (intuitively clear) interpretation of expressions and function de nitions as graphs and rewrite rules respectively. Instead of using drawings, like above, or 4-tuples (see Barendregt et al. (1987) and Barendsen and Smetsers (1994)), we specify graphs in an equational style (cf. Barendregt et al. (1987), Ariola and Klop (1995)). Each equation is a node speci cation of the form n = S(n 1 ; : : : ; n k ) where n; n 1 ; : : : ; n k are variables. Moreover, the topmost node (root) is indicated explicitly. E.g., the graph in Example 3.2 (i) can be denoted by hz j fz = F(c); c = Cons(x; g); g = G(x; z); x = 0 gi: De nition 3.3 A graph is a tuple g = hr j Gi. The variable set of g (notation V(g)) is the collection of variables appearing in r; G. The set of free variables of g (notation FV(g)) consists of those in V(g) that do not appear as the left-hand side of an equation in G; the other (bound) variables are indicated by BV(g). We will identify graphs that only di er in the names of bound variables.
Using this formalism, it is easy to de ne the interpretation of expressions as graphs. Our type systems for expressions deal with the full syntax of De nition 3.1. However, to provide a simple and direct translation to graph rewrite systems we only consider case expressions in function de nitions at the topmost level, distinguishing cases as to one of the input variables. This is no serious restriction: it is always possible to introduce auxiliary functions to express nested pattern matching.
De nition 3.4 For each expression E, the graph interpretation of E (notation E] ]) is dened inductively as follows. The denotation x :=r] stands for simultaneous substitution ofr for (the free occurrences of)x.
x] ] = hx j ;i; SẼ] ] = hr j fr = S(r)g G i where hr i j G i i = E i ] ] and r fresh, let x = E in E 0 ] ] = hr 0 j G G 0 i x := r]; letrecx =Ẽ in E 0 ] ] = hr 0 jG G 0 i x :=r]: We have omitted the case construct: it will be treated in the translation of function de nitions. Note that our interpretation is such that FV(E) = FV( E] ]).
The interpretation of expressions naturally gives rise to an equivalence relation on these expressions.
De nition 3.5 The expressions E and E 0 are graph equivalent (notation E E 0 ) if Once we have interpreted expressions we can interpret function de nitions.
De nition 3.6 (i) The graph interpretation of a function de nition Fx = E is speci ed as follows. We distinguish two cases: Case For a formal de nition of graph rewriting the reader is referred to Barendregt et al. (1987) (see also Barendsen and Smetsers (1994)).

Higher-order functions
In term graph rewriting all symbols have a xed arity. Moreover, there is no abstraction operator (like ) to construct anonymous functions. This prevents the use of functions as arguments or as results.
The usual way (in functional programming languages) to incorporate higher-order functions is to admit partial (often called Curried) applications. These are written as FE 1 E k (with k < arity(F)), denoting the function x:F(E 1 ; : : : ; E k ; x k+1 ; : : : ; x arity(F) ).
Partial applications can be simulated in graph rewriting by introducing auxiliary symbols F k and writing FE 1 E k as F k (E 1 ; : : : ; E k ) (so F arity(F) = F). Moreover, we add an application operator Ap to our syntax which collects arguments, i.e. (roughly), Ap(F k (Ẽ); E 0 ) = F k+1 (Ẽ; E 0 ): See Barendsen and Smetsers (1993) for a detailed description of the graph rewriting semantics.
We will present our type systems rst for the traditional, purely algebraic, syntax and then describe the type-theoretic extension dealing with partial applications. For conventional typing this extension is straightforward. In the case of uniqueness typing, however, this turns out to be a subtle matter.

Conventional Typing
The notion of conventional typing is common in most functional programming languages. It combines simple Curry typing with an instantiation mechanism to deal with di erent occurrences of function and constructor symbols. This weak form of polymorphism is necessary due to the separation of speci cations (function de nitions, algebraic types) from applications.

Syntax
De nition 5.1 Types are built up from type variables and type constructors.
::= j T~ j 1 ! 2 : Here, T ranges over type constructors which are assumed to be introduced by an algebraic type system A. The function space type constructor ! is used when dealing with higher-order functions. We will treat these at the end of this section. We rst associate a type with the constructors and function symbols in our language. The notion of type assignment for expressions is parametric in the choice of these symbol types.
De nition 5.2 A symbol type of arity k is a k+1 tuple ( 1 ; : : : ; k ; ). We will sugestively denote this as ( 1 ; : : : ; k ) B : The types~ are called argument types and is the result type.
De nition 5.3 (i) Let A be an algebraic type system. The speci cations in A give the types of the algebraic constructors. Let T~ = C 1~ 1 j be the speci cation of T in A. Then  A`C i :~ i B B;x i :~ i`Ei : 0 (pattern matching) B`case E ofPjẼ : 0 (if P i = C ixi ) (iii) A function de nition Fx = E is called type correct if x :~ `E : where~ B is the standard type of F. A collection of function de nitions is type correct if its members are type correct in the above sense.

Semantics
We will show that the type system is sound and complete with respect to graph rewriting. We rst recapitulate the notion of typing for graphs and rewrite rules from Barendsen and Smetsers (1993). This notion is a graph-theoretic variant of the typing concept presented in van Bakel et al. (1992) for Term Rewrite Systems.
De nition 5.5 (TGRS Graph typing) Let g = hr j Gi be a graph. A typing for g is a function T assigning a type to each element of V(g) such that for any equation x = S(ỹ) in G F; A`S : T (ỹ) B T (x): That is, T is a type assignment to nodes that satis es`local correctness'. We say that T types g with (notation T (g) = ) if furthermore T (r) = . Moreover, g is typable with (notation g : ) if there exists T with T (g) = .
Now we can give a semantic notion of expression typing.
De nition 5.6 Let E be an expression.
(i) We say that T types E with (notation T j = E : ) if T ( E] ]) = .
(ii) This notation is extended to sequences (in particular, bases): T j = B i T j = x : for each (x : ) 2 B.
(iii) By B j = E : we denote that B is extendible to a typing of E] ], i.e., for some T one has T j = B and T j = E : : Proposition 5.7 (Soundness of expression typing) For any B; E; B`E : ) B j = E : : Proof. By induction on the derivation of B`E : .
Proposition 5.8 (Completeness of expression typing) For any B; E; B j = E : ) B`E : : Proof. By induction on the structure of E.
Corollary 5.9 B`E : ; E E 0 ) B`E 0 : Typing of graph rewrite rules can be formulated as follows.
De nition 5.10 (TGRS Rule typing) (i) A type assignment T to variables can be extended to algebraic patterns in a straightforward way: F; A`C :~ B ; T (p) =~ ) T (Cp) = : (ii) Say the standard type of F in F is~ B . Then the rewrite rule Fp ! g is type correct if for some T one has T (p) =~ ; T (g) = : Note that the type assignment to the patternp is uniquely determined by the input types : given C and , there is at most one sequence~ such that F; A`C :~ B .
(iii) A collection of rewrite rules is type correct if every member is.
Proposition 5.11 (Soundness of function typing) F is type correct ) F] ] is type correct.

Subject Reduction
The following is proved in Barendsen and Smetsers (1993).
Theorem 5.12 (TGRS Reduction typing) Suppose R is type correct. Then g : g ! ! R g 0 ) g 0 : : Proof. Sketch] If a rewrite rule (say with typing T , cf. De nition 5.10) applies to a certain typed graph g, then there is a substitution such that T (on the pattern of the rule) corresponds to the typing of the matching part of g. Now T (on the result of the rule) can be used to type the contractum.
By our soundness and completeness results, the so-called Subject Reduction Property is an easy corollary of the previous theorem.
Subject Reduction Theorem 5.13 Suppose F is type correct. Then B`E : Type Inference In this section we will show that type assignment has the principal type property: if an expression E is typable then there exists a most general typing for E. The presentation below has been inspired by Barendregt (1992). The idea of strictly splitting type reconstruction into generation of equations and uni cation is due to Wand (1987). The present algorithm is an inductive variant of the procedure on graphs described in Barendsen and Smetsers (1993).
De nition 5.14 (i) A type equation is an expression of the form ' .
(ii) Let E = f 1 ' 1 ; : : : ; n ' n g be a nite set of type equations. A solution for E is a substitution such that 1 = 1 ; : : : ; n = n : In that case one writes j = E. The notion of most general solution for E is de ned as usual.
Uni cation Theorem 5.15 There exists a recursive function Unify having as input nite sets of equations between types such that E has a solution ) Unify(E) is the most general solution for E; E has no solution ) Unify(E) = fail: Proof. See Robinson (1965). The next step is to associate with each expression E a set of type equations in such a way that typability of E can be formulated in terms solvability of those equations.
(i) Let be a type. Then ; 0 are equivalent with respect to (notation 0 ) if ( ) = 0 ( ) for all occurring in .
(ii) This notion is extended sequences of bases and/or types: we write B; 0 if 0 for all types appearing in B; .
Higher-order Typing The type system can be extended to deal with higher-order functions (see Section 4), using the function space type constructor !.
The (standard) types of the`Curried' function symbols F k for partial applications are obtained from the (standard) type of F, in the following way (set F arity(F) = F).
The new syntactic construct Ap is treated by an additional rule.
The results of this section (soundness, completeness, subject reduction, principal typing) extend to the higher-order system. As to principal typing, the equations for Ap are generated by The function space constructor is allowed inside algebraic type de nitions: for example Object( ) = C( ; ! ; ! Int):

Introduction to Uniqueness Typing
Uniqueness typing o ers the possibility to indicate reference count requirements of functions in the corresponding argument types.
The idea of restricting occurrences of input objects by a type system is not new: we can make use of ideas developed in so-called resource conscious logics like linear logic. Via the propositions-as-types correspondence (relating inputs to assumptions and functions to proofs) restrictions on usage of assumptions in these logics gives the desired reference count limitations.
Since we deal with both destructive and harmless operations, a purely linear typing system (in which neither copying nor discarding of input is allowed) is too restrictive for our purposes. Instead, we propose to divide the type system into two layers: a`resource conscious' part in which occurrences are limited, and a`conventional' part with no reference restrictions. In fact, the former layer (of`unique' types, indicated by ) admits discarding input but excludes copying. Therefore it corresponds to a ne logic (see Blass (1992)) in which weakening is present but no contraction. The latter layer (of types) corresponds to ordinary (intuitionistic) logic with the same strength as conventional typing.
The two layers are connected: it is possible to move from the layer to the layer. These transitions are regulated by the type system: we have a subtype relation allowing a unique object to be seen as a conventional one (in case the accessing function has no reference requirements) and a type correction mechanism (forcing an object with reference count greater than 1 to be regarded as non-unique).
The operator ! in linear logic should not be confused with the attribute : the type indicates that there are no reference restrictions, whereas ! would stand for`as many (duplicatewise linear) copies as necessary'.
We will now explain the graph-theoretic intuition of our type system. In symbol types, it can be speci ed that a given argument should be unique (by the annotation ). Type correctness means that in any application the concrete function argument should have reference count 1. So the function has indeed`private' access to its argument, and hence the argument can be updated in-place.
This analysis was intended for inherently destructive operations and their parameters, like WriteChar, but can also help to improve storage management. Consider, for instance, the following list reversing function which can be implemented e ciently as à destructive' function if the given uniqueness type is used.
Nil j`2: Note that H's rst argument has reference count 1 in any type correct application. The topmost node of this argument is not used in the result of the function. Hence this node becomes obsolete and can be re-cycled: not only its space but also also parts of its contents. In fact it already su ces to change the reference to t to point to`2. Such re-usage of space is often called compile-time garbage collection.
We have seen that the environment type F : B speci es that F's argument should be unique for F. In the same way, uniqueness of results is speci ed: if G : B , then a well-typed expression F(G(E)) remains type-correct, even if G(E) is subject to computation.
The above-mentioned transitions between the type layers are motivated as follows.
Sometimes, uniqueness is not required. If F : B then still F(G(E)) is type correct. This is expressed in the subtype relation , such that roughly . O ering a nonunique argument if a function requires a unique one fails: . The subtype relation is de ned in terms of the ordering on attributes. In an application an argument can also be non-unique if it has reference count greater than 1 (even though the type of the argument expression itself is unique). This is covered by a correction mechanism: a unique result may be used more than once, as long as only non-unique supertypes are required.
From the types given above it can be seen that the layers and are have some internal structure induced by the presence of type constructors: a type (at the outer-most level) can have parts marked with (and vice versa). This ne structure, with the possibility of specifying a ne or conventional behaviour of substructures, is a powerful feature of our system. Pattern matching (expressed by the case construction) is an essential aspect of term graph rewriting, causing a function to have access to`deeper' arguments via data paths instead of a single reference. This gives rise to`indirect sharing' of objects by access via intermediate data nodes. For example, if a function F has access to a list with non-unique spine, the list elements should also be considered as non-unique for F: other functions may access them via the spine. This e ect is taken into account by a restriction on the uniqueness types of data constructors: the result of a constructor is unique whenever one of its arguments is. For the constructor Cons of lists, for example, the possible uniqueness variant are: ( ) (3) With (1) ordinary lists can be built.
(2) can be used for lists of which the`spine' is unique, and (3) for lists of which both the spine and the elements are unique. Observe that in the above example, the List argument of Cons is always attributed in the same way as the corresponding List result. In general, such a uniform way of attributing recursive occurrences of a type constructor leads to homogeneous data objects: All recursive parts of such an object have the same uniqueness properties as the object itself. A procedure for generating consistent attributions of arbitrary data types can be found in Barendsen and Smetsers (1993).
We can also express propagation by using the relation. E.g.
is well-attributed if v u. Note that this indeed excludes a constructor for List (Int ). A similar restriction on types of data constructors can be found in the type systems of Guzm an and Hudak (1990) and Turner et al. (1995). Some parts of the uniqueness type system are complicated. The treatment of cyclic dependencies is subtle; moreover dealing with higher-order functions is a non-trivial matter. This seems to be a common aspect of related approaches.
The way references are counted can be re ned, by making use of information on the evaluation order. To avoid unnecessary complications we will not treat this in detail but give an idea of the method at the end of Section 8.

Simple Uniqueness Typing
Algebraic Uniqueness Types Uniqueness types are constructed from conventional types by assigning a uniqueness attribute to each subexpression. We will denote the attributes as superscripts; for nonvariable types these are attached to the topmost type constructor of each type. Below, S; T; : : : range over uniqueness types and u; v; : : : over the attributes ; . The outermost attribute of S is denoted by pSq. Moreover jSj denotes its underlying conventional type.
We will rst describe the system without the type constructor !. De nition 7.1 The subtype relation is very simple: the validity of S S 0 depends subtypewise on the validity of u u 0 with u; u 0 attributes in S; S 0 . One has, for example, List u (List v (Int w )) List u 0 (List v 0 (Int w 0 )) i u u 0 ; v v 0 ; w w 0 : In order to account for multiple references to the same object we introduce a uniqueness correction.
De nition 7.2 For each S, we construct the smallest non-unique supertype S] of S, as follows. u ] = ; T uS ] = T S : The last clause possibly introduces types like List (Int ). Contrasting Turner et al. (1995), we allow these types in our system. This is harmless since these`inconsistent' types have no proper inhabitants (for example, there is no Cons yielding type List (Int )).
Type correction is applied when dealing with plain sharing (through multiple occurrences of the same variable). In a`resource conscious' system these variable duplications are easy to detect: they correspond to contraction steps in the logical setting. The treatment of recursive objects (occurring as letrecx =Ẽ in E 0 ) is special: we account for possible cycles by correcting both internal (inẼ) and external (in E 0 ) references to their rootsx.
The notion of standard type is adapted in the following way. As can be seen from the List example, there are several standard types for each data constructor. De nition 7.3 (i) As before, standard types of function symbols (F :SBT) are collected in an environment F.
(ii) Say the algebraic environment A contains T~ = C 1~ 1 j A set of standard types for C i consists of attributed versions of the conventional typẽ i B T~ , such that (1) multiple occurrences of the same variable and of the constructor T have the same uniqueness attribute throughout each version; (2) each version is uniqueness propagating; (3) the set contains at most one version for each attributed variant of T~ .
This leaves some freedom as to the choice of attributes on positions not corresponding to T;~ . Barendsen and Smetsers (1993) o er a general method for constructing a reasonable set of standard types for each constructor. In most cases (like List, see above), however, the choice of attributes of T~ xes those for the~ i . From now on we assume that standard types have been determined. For these standard typesSBT we set A`C :SBT as before. Like in linear logic, we have to be precise when dealing with bases used for typing subterms. In particular, duplicating and discarding of inputs are treated explicitly. The denotation B 1 ; B 2 stands for a disjoint union of bases.
(i) The rules for type assignment are the following. In the derivation one clearly recognizes the`logical' di erence between the a ne ( ) and conventional ( ) layer: with respect to one only has weakening as structural rule, whereas admits both weakening and contraction since S] = S if pSq = .
Higher-Order Uniqueness Types The treatment of higher-order functions in the uniqueness type system is a subtle matter.
Types of partial applications FẼ need to be assigned a uniqueness attribute. If these partial applications contain unique subexpressions one has to be careful. Consider, for example, a function F with type F : ( ; ) B in the partial application FE. Clearly, the result type of this application is of the form u ! . If one allows that this application is used more than once, one cannot guarantee that the argument E (with type ) remains unique during evaluation. E.g. if FE is passed to a function G(f) = (f0; f1), the occurrences of f will result in two applications of F sharing the same expression E. Apparently, the FE expression is necessarily unique: its reference count should never become greater than 1, i.e. it is not allowed to move from the a ne to the conventional type layer. There are several ways to achieve this. For instance, one might introduce a new uniqueness attribute, say 4 , for any unique object that does not coerce to a non-unique variant. This has been described in Barendsen and Smetsers (1993). Another solution is the region-administration introduced by Reynolds (1995).
Instead of introducing a new attribute, the present paper assigns the attribute to the above !-type, but considers the ! constructor in combination with the attribute as special: it is not permitted to discard its uniqueness. The leads to an adjustment of the subtyping relations as well as of the type correction operator ].
As to the subtyping relation, the attributes of corresponding occurrences of the ! constructors (in the left-hand and the right-hand side of an inequality) should be identical. The same is required (to ensure substitutivity of the subtyping relation) for variables. The subtyping relation becomes inherently more complex than in the algebraic case because of the so-called contravariance of ! in its rst argument: S u ! S 0 T u ! T 0 , T S; S 0 T 0 : Since ! may appear in the de nitions of algebraic type constructors, these constructors may inherit the co-or contravariant subtyping behaviour with respect to their arguments. We can classify the`sign' of the arguments of each type constructor as (positive, covariant), (negative, contravariant) or > (both positive and negative). In general this is done by analyzing the (possibly mutually recursive) algebraic type de nitions by a xedpoint construction, with basis sign(!) = ( ; ). Notation. The variants , and > are de ned in terms of , as follows. Here, ũ stands for the so-called cumulative uniqueness attribute ofũ: it equals whenever some u i is , and otherwise. The typing rule for Ap is de ned straightforwardly.

Semantics
We start with de ning a notion of uniqueness typing for graphs, based on type assignment to nodes in graphs. Subtyping and type correction will be done along references to objects, whereas on expressions one can perform coercions regardless of their context. This di erence becomes apparent in the root of a graph. By making a small adjustment (introduced in Barendsen and Smetsers (1993) as a tool to obtain subject reduction) we can reconcile the two approaches.
De nition 7.7 (i) Let g be a graph. Then g + is the graph that results from g by adding a new root r + with in-degree 0 containing the data symbol Root of arity 1, pointing to the root r of g.
(ii) The standard types of Root are given by u B u . Since Root is not a function, the root of g + will never be involved in the rewrite process. Furthermore, for each cycle in g + there is always an external reference (i.e., a reference from a node that is not part of the cycle) to that cycle. This makes cycle and sharing detection more uniform.
De nition 7.8 Let n be a node in g. The reference count of n in g (notation rc g (n) or just rc(n)) is if n appears more than once in the right-hand sides of equations in g + , and otherwise.
Note that the above mechanism only di ers from ordinary reference counting at the root of the graph, notably when the root is part of a cycle. De nition 7.9 (TGRS uniqueness graph typing) Let g be a graph.
(i) A uniqueness typing for g is a function T assigning a uniqueness type to each node in g + such that for any node speci cation x = S(ỹ) there exist typesS with the following properties. (ii) We say that T types g with S (notation T (g) = S) if moreover T (r + ) = S. Furthermore g is typable with S (notation g : S) if T (g) = S for some T .
The constraints in the above de nition re ect the uniqueness property of function applications mentioned in Section 6. If, say, F with arity 2 has a standard type in which the rst argument is unique, then for any application x = F(y; z) in a type correct graph g we have that rc g (y) = 1. The following subsection shows that this property is indeed established by the natural deduction system.

Soundness
As a rst step towards the soundness proof we need the following technical results. De nition 7.10 (i) S] = S]; S] = S.
(ii) By T j = B we denote that T (x) = S for each (x:S) 2 B.
Lemma 7.11 Let B`E : S. Set r E = r E]] , rc E = rc E]] (r E ). Then there exists a type assignment T such that T is a uniqueness typing for E] ] and moreover T j = B; T (r E )] rcE S: Proof. By induction on the derivation of B`E : S. We will only consider two cases: application and contraction. All other cases are handled in the same way.

Completeness
Showing that the inductive uniqueness type system is powerful enough to capture uniqueness typing of graphs is more involved than for the conventional case. This is because our typing rules are rather intensional: Due to the pessimistic treatment of letrec-expressions (type correction even in the case of a degenerate cycle) there are expressions E; E 0 and type S such that E] ] = E 0 ] ], E is typable with S whereas E 0 is not typable at all.
The idea is to transform a given graph g = hrjGi into an expression g~that contains à minimal' amount of letrec-expressions. This is done by stepwise substitution of equations in G corresponding to nodes with reference count 1. Take, for example, the following graph. De nition 7.14 Let g = hrjGi be a graph. Say E n is the right-hand side of the equation in G corresponding to variable n. (i) The expressions E n are translated into expressions E n , as follows.
The above transformation is an instance of the hiding operation de ned by Ariola and Klop (1995).
It is not completely trivial that the (mutually recursive) de nition of and is sound. To see that this is indeed the case consider the following measure on g-nodes.
De nition 7.15 Let n 2 V (g). Then n is said to have degree 0 if n 2 FV(g) or n has no arguments with reference count . Otherwise, if the maximal degree of n's arguments with reference count is d, then n has degree d + 1. This is a sound de nition: since there exists no in nite path of nodes with reference count , each node n can be assigned a unique, nite degree, denoted by deg(n).
It is clear that the degree of nodes decreases with each recursive occurrence of the operator above. Lemma 7.16 g~] ] = g Proof. Obvious. Below we will use the degree as a technical tool to prove that g~can be typed with the same type as g. In the sequel, x a graph g and an uniqueness typing T for g. De nition 7.17 (i) The initial basis (of g) (notation B I ) is the set B I = fn : T (n)] rcg(n) j n 2 FV(g)g: (ii) The recursion basis (notation B R ) is the set B R = fn : T (n)] j rc g (n) = g: Lemma 7.18 For all n 2 V(g) one has (i) B I ; B R`E n : T (n); (ii) B I ; B R`n : T (n)] rcg(n) .
Proof. By simultaneous course-of-values induction on the degree of n. Suppose (i) and (ii) hold for all nodes with degree < d. Let n have degree d.
(i) Say E n = S(n 1 ; : : : ; n k ) and F; A`S :S B T with T (n) = T and T (n i )] rc(n i ) S i for all i k. Claim. B I ; B R`n : S i : Then we are done: we can complete the derivation using the rules application and contraction. The latter deals with multiple occurrences of the variables in B I ; B R ; note that ] is idempotent, i.e. S]] = S] for each type S. Proof. Let i k. Case 1. rc(n i ) = and n i 2 BV(g). Then by induction hypothesis (ii) (note that deg(n i ) < d) we have B I ; B R`n i : T (n i ): Now we can apply subsumption.
Case 2. rc(n i ) = and n i 2 BV(g). Then B I ; B R`n i : T (n i )]; by variable and weakening, so by subsumption the result follows.
Case 3. n i 2 FV(g). Then B I`n i : T (n i )] rc(ni) . Again by subsumption the result follows. Claim (ii) The case rc(n) = and n 2 BV(g) is covered by (i). Otherwise, either B R (in case n 2 BV(g)) or B I (in case n 2 FV(g)) contains n : T (n)] rc(n) . Now we are done by variable and weakening. Proposition 7.19 B I`g~: T (g): Proof. Since T is a typing for g we have T (r)] rc(r) T (r + ) by the standard type for Root. Now by Lemma 7.18, using the rule cycle and the rule weakening (also to deal with multiple occurrences of the variables in B I ) and subsumption the result follows. De nition 7.21 (TGRS Rule uniqueness typing) (i) A uniqueness type assignment T to variables can be extended to patterns in the following way: F; A`C :S B T; T (p) =S ) T (Cp) = T: (ii) Say the standard type for F in F isS B T . Then the rewrite rule Fp ! g is (uniqueness) type correct if for some uniqueness typing T one has T (p) =S; T (g) = T: (iii) A collection of rewrite rules is type correct in F if every member is. Proposition 7.22 (Soundness of uniqueness function typing) F is uniqueness type correct ) F] ] is uniqueness type correct: Proof. Straightforward.

Subject Reduction
Theorem 7.23 (TGRS Uniqueness reduction typing) Suppose R is uniqueness type correct. Then for any g; h; S g : S g ! ! R h ) h : S: Moreover the latter type assignment coincides with the original for g with respect to the free variables of h. Proof. See Barendsen and Smetsers (1993). Finally, by combining this result with the results from the previous subsection we can formulate the soundness of the uniqueness type system for expressions with respect to graph rewriting. Proof. First note that F] ] is type correct by Proposition 7.22. Suppose B`E : S and E ! ! F E 0 . Then B j = E : S by soundness (Theorem 7.13). By Theorem 7.23 we have B j = E 0 : S. Hence by completeness (Theorem 7.20) the result follows.

Polymorphic Uniqueness Typing
In order to denote uniqueness schemes, we extend the attribute set with attribute variables (a; b; a 1 ; : : :). This increases the expressiveness of the type system. Moreover, attribute polymorphism is needed for the determination of`principal' uniqueness variants of typings.
Uniqueness constraints are indicated by ( nite) sets of attribute inequalities called attribute environments. For example, the standard type of the symbol Cons is now expressed by Cons : ( a ; List b ( a )) B List b ( a ) j b a: Note that this expression captures the collection of standard types for Cons in one single type. The former types for Cons can be obtained by substituting concrete attributes for a and b satisfying the requirement a b. The same is done for all symbols: each symbol has one polymorphic standard typeS B T j ?.

Syntax
All notions of the previous section (type environment, subtyping, type derivation) are re-de ned relative to attribute environments.
De nition 8.1 (i) As to the attribute relation , we say that u v is derivable from the attribute environment ? (notation ?`u v)  The environments ? in the deduction system are global in the sense that they may contain auxiliary uniqueness constraints (attribute inequalities appearing in some derivation step, but not occurring in the nal basis and type). In order to eliminate these super uous constraints in the conclusion of a deduction, we re ne the notion of derivability.
De nition 8.5 (i) Let ?, ? 0 be coercion environments, and let S be a uniqueness type.
Then ?; ? 0 are equivalent with respect to S (notation ? S ? 0 ) if for all attributes u; v in S; ; ?`u v , ? 0`u v: (ii) This denotation is extended to bases and/or types: we write ? B;S ? 0 if ? T ? 0 for all T appearing in B; S.
De nition 8.6 (i) A polymorphic uniqueness typing statement is an expression of the form B`E : S j ?: Such a statement is derivable if there exists a consistent ? 0 such that ? 0 B;S ? and B`?0 E : S can be produced via the above axioms and rules.
(ii) Say the standard type for F in F isS BT j?. Then the function de nition Fx = E is type correct ifx :S`E : T j ?: Formulating the notion of attribute instance (via attribute substitutions ) for polymorphic uniqueness typing is more subtle than for conventional type instantiation. One has to take into account that the uniqueness information is divided into two parts: uniqueness types and coercion environments. For example, the typings Int a j a and Int have the same`uniqueness content', but the uniqueness information is denoted in two di erent ways. The following de nition of instantiation focusses on the uniqueness content, abstracting from the speci c type denotation.
De nition 8.7 (i) The typing S 0 j ? 0 is a uniqueness instance of S j ? (notation S 0 j? 0 Sj?) if S; S 0 have the same conventional skeleton (jSj = jS 0 j) and there exists an attribute substitution such that ? 0`? ; S 0 = ? 0 S : (ii) We also use this denotation for sequences of types:S 0 j? 0 S j?.
The following expresses that attribute variables and attribute environments can be regarded as uniqueness schemes: all instances of a given typing are correct.

Semantics
The semantic results of Section 7 go through in the polymorphic system. Below we reformulate the main results.
De nition 8.9 (TGRS polymorphic uniqueness graph typing) Let g = hr j Gi be a graph. A polymorphic uniqueness typing for g is a pair hT ; ?i where T is a uniqueness type assignment to nodes in g and ? is a consistent coercion environment such that for any equation x = S(ỹ) in G there exist typesS with the following properties.
F; A`S :S B T (x) j ?; and for all i k T (n i ) ? S i if rc g (n i ) = , T (n i )] ? ? S i if rc g (n i ) = : The following de nition prepares for the soundness result.
De nition 8.10 E an expression and S a uniqueness type.
(i) Let B be a basis. By T j = ? B we denote that T (x) = ? T for each (x:T) in B.
(ii) We say that T types E with S in ? (notation T j = ? E : S) if hT ; ?i is a uniqueness typing for E] ] + such that T ( E] ] + ) = ? S.
(iii) By B j = E : S j ? we denote that for some T and ? 0 B;S ? T j = ? 0 B; T j = ? 0 E : S: Uniqueness Type Inference In this section we will describe how to compute uniqueness variants of conventional typings. The presentation will proceed along the same lines as the conventional case: given an expression, we collect a`minimal' set of requirements (this time in the form of inequalities). It will be decidable whether this set has a solution; moreover, in the positive case a`principal' solution is computable. For the graph theoretic setting, uniqueness type inference has been described in Barendsen and Smetsers (1995b). In order to generate uniqueness requirements in an inductive way, we construct a syntax-directed variant of the type derivation system. The substitution in the contraction rule is a global operation which does not t into a syntax-directed (decompositional) system. Therefore we introduce variable annotations for administration of multiple variable occurrences.
We assume that the applied occurrences of variables in our expressions are marked: x if x either occurs more than once or x is a letrec-variable, and x if x occurs only once. De ning occurrences (let x = ) are not marked. This marking corresponds to a simple reference-count determination in graphs.
The subsumption rule is incorporated in the rules (variable) and (application). The contraction rule has become obsolete by our new administration of sharing: uniqueness correction can now be combined with the (variable) rule. Weakening is taken into account by allowing a larger basis in the rules. Moreover, strict separation of bases for typing is not longer necessary, again by our local administration of multiple variable occurrences.
De nition 8.14 The syntax directed polymorphic system looks as follows. Derivability in the resulting (syntax directed) system is denoted by`s d . where E ? results from E by removing all markings , .
We need an equivalent of the statements E that were used in the conventional case. De nition 8.16 (i) An attribute inequality is an expression of the form u v, where u; v are uniqueness attributes. A type inequality statement is an expression of the form S T , where S; T are uniqueness types. The expression S ' T stands for the combination S T; T S.
(ii) A system of uniqueness requirements is a pair U = hS; i, where S consists of type inequality statements and of attribute inequality statements.
(iii) For each U, the set jUj is the underlying conventional set of equations jSj = jTj associated with the inequality statements S T in U. De nition 8.17 (i) A uniqueness type substitution is an assignment of uniqueness types to uniqueness type variables such that p ( u )q = u for each u in 's domain.
(ii) A solution for a system U = hS; i consists of a substitution and a consistent coercion environment ? such that (1) S ? T for each (S T ) in S.
In this case we write ; ? j = U.
In the sequel we will express uniqueness typing constraints in the form of a system U. Towards a procedure for solving such a system, we consider the case where a partial solution has been determined that`conventionally satis es' U, i.e. j j j = jUj. We now focus on determining a suitable ? which solves the remaining inequalities by so-called uniqueness uni cation.
In view of this, the uni cation algorithm takes`conventionally correct' systems as input, i.e., systems in which for all inequality statements S T we have jSj = jTj. Lemma 8.18 Consistency of attribute environments is a decidable property.
Proof. Note that ? is consistent i the`transitive closure' of ? does not contain . This can be veri ed e ectively by the niteness of attribute environments. In practice, the strategy to solve a system U will be based on a conventional typing algorithm. We will describe how to combine the attribution procedure with a lifting concept: given a system U and a conventional solution 0 of jUj we can compute a`most general' uniqueness variant ; ? of 0 (if it exists) solving U. The result is called an attribution of 0 .
We rst have to de ne the notion`most general attribution', using the concept of attribute instantiation, cf. De nition 8.7.
De nition 8.20 (i) The pair ( 0 ; ? 0 ) is an instance of ( ; ?) if for some where the latter equation is to be taken argumentwise.
(ii) A (conventional) solution 0 of jUj is called attributable if there exists a uniqueness substitution with j j = 0 and a consistent environment ? such that ; ? j = U: The above de nition of instantiation induces a notion of principal attribution.
Principal Attribution Theorem 8.21 Let U be a system of uniqueness requirements. It is decidable whether a given (conventional) solution of U is attributable. Moreover, if this is the case, a principal attribution can be computed.
Proof. Sketch of the algorithm] Given 0 j = jUj, lift 0 to a uniqueness type substitution by choosing fresh attribute variables at each subtype, such that outermost attributes correspond to the attributes of variables in U. Now compute attr(U ). If this gives fail, then 0 is not attributable. Otherwise (say attr(U ) = ?) output ( ; ?). Analogous to the situation in conventional typing, we formulate a notion of`exactness' to express that a certain system precisely captures the minimal uniqueness requirements needed for a valid typing.
De nition 8.22 A system of uniqueness requirements U is called uniqueness exact for B; E; S if for all ; ?
(1) ; ? j = U ) B `s d E : S j ?: (2) B `s d E : S j ? ) 0 ; ? 0 j = U for some 0 ; ? 0 such that 0 ; ? 0 B;S ; ?: Proposition 8.23 Let E be an expression, B a basis and S a uniqueness type. Then there exists a nite system of requirements U = U(B; E; S), computable from B; E; S, such that U is exact for B; E; S.
Proof. The following inductively de nes U(B; E; S). Union of requirement systems is to be taken componentwise. if P i = C ixi ; the standard type of C i isT i B R i j i ; ; a fresh: The veri cation is similar to the one in the conventional case. As to variables x , note that S] ? ? S 0 , S ? S 0 ; ?`pS 0 q = : As in the conventional case, the typing procedure is started with parameters that do not impose any restriction on solutions, cf. the proof of Theorem 5.20.
De nition 8.24 Let E be an expression, say with FV(E) = fx 1 ; : : : ; x n g. The basic system for E is the system U(E) = U(B 0 ; E; S 0 ), where B 0 = fx 1 : 1 a 1 ; : : : ; x n : n a n g and S 0 = a .
The above discussion suggests the following strategy for determining uniqueness types.
Given E, determine a (conventional) solution 0 of jU(E)j; then use the Principal Attribution Theorem to lift this solution to a uniqueness typing. If this succeeds (say with output ; ?), then conclude B 0`? E : S 0 .
A natural attempt is to take the most general conventional solution for 0 . However, because of our treatment of higher-order functions (involving a restriction on the subtype relation w.r.t. variables), it might be the case that lifting this most general solution fails, whereas some speci c instance is attributable. Therefore, a reasonable notion of`most general solution' cannot be formulated for the combination ; ?. Consequently, there is no`Principal Uniqueness Type Theorem'. Instead, we stick to the asymmetric approach suggested by the notion of principal attribution with respect to a given (previously determined) substitution. This is re ected in the description of the typing procedure in Clean.

Uniqueness Type Inference in Clean
In order to translate the above into a suitable actual typing algorithm we indeed try to lift the most general solution of jU(E)j. If this attempt fails, however, we do not try any speci c instances but consider the expression untypable.
As a consequence, the underlying conventional typings of the derived uniqueness types are exactly the principal ones, so from the programmer's point of view the uniqueness system is a transparent extension of conventional typing: if one disregards the uniqueness information the types are as one would expect.
Having seen how to derive expression typings in a given environment, we can focus on type inference for functional programs. As in any other functional language, in Clean type checking is concerned with the determination of a suitable environment type for each function symbol, such that all program parts are well-typed.
By our de nition of function typing, this boils down to determining uniqueness types for the right-hand expressions of the function de nitions, using the above procedure. The only problem is the possibility of (mutually) recursive function speci cations. It is well-known that typing of these de nitions is undecidable in general.
In fact, the Clean compiler adopts the Hindley-Milner approach towards recursion: in the de nition of, say, F, all occurrences of F should be typed with F's environment type (i.e., without instantiation). Indirect recursion is treated similarly. This can be achieved, for instance, by adjusting the de nition of U(B;E; S) for E = SẼ in the proof of Proposition 8.23.
Alternative reference count analysis A straightforward (static) reference counting treats all references to a given object in the same way. This can be re ned: multiple access to a unique argument is harmless if one knows that only one of the references will be present at the moment of evaluation. An example of this evaluation-strategy-aware (dynamic) reference counting is the treatment of conditional expressions in Clean. For example, if we de ne the conditional by Cond(b; x; y) = case b of True j x False j y and compute Cond(B; E; E 0 ) in the standard way, the condition is evaluated rst (with possible sharing between B and E; E 0 ) and subsequently one of the alternatives is chosen and evaluated (so sharing between E and E 0 has disappeared). This suggests that we can distinguish between references to the same object inside B; E and E 0 respectively, allowing a less restrictive uniqueness typing.
Note that the syntax directed system of De nition 8.14 provides the possibility to have di erent markings of the same variable. In view of the above analysis, the following expression is well-marked: let x = A in Cond(F(x ); G(x ); H(x )): In fact, the results of Barendsen and Smetsers (1993) already abstract from the way references are counted: they capture both the standard and the re ned approach.

Conclusions and Related Work
We have developed a very powerful type system in natural deduction style. Its aim is to characterize reference structures in graphs, in order to express uniqueness constraints of function arguments. In the present paper, polymorphism has been extended to uniqueness attributes. Both soundness (with respect to a graph rewriting semantics) and decidability of resulting system have been shown.
The system has been implemented as part of the Clean-compiler. The present work has been inspired by Guzm an and Hudak (1990), addressing the mutability problem in a`single threaded polymorphic lambda calculus' (polyst ). Instead of using an operational semantics directly based on graph rewriting, they apply lambdagraph reduction due to Wadsworth (1971). Type reconstruction is (roughly) described by de ning a type inference algorithm, refraining from a formal correctness proof.
In Turner et al. (1995), a type system is presented that is strongly related to ours. However, the design was guided by di erent motives: its main purpose is to deal with program transformations (in particular, inlining of unique expressions) and with superuous closure updates. The main di erence with our system is that uniqueness (use 1, using their terminology) is not a property of a reference to an expression but rather of the expression itself. The subtyping relation (in our system needed to adjust an o ered argument type to the corresponding requested type) is absent, since it would destroy the intended uniqueness property.
In spite of the fundamental e orts of Guzm an and Hudak (1990) and Turner et al. (1995), none of the described approaches has been turned into a real implementation.
Type systems with subtyping have, among others, been studied in Mitchell (1991), presenting a type inference algorithm which determines the minimal set of coercions necessary to type a given term. The algorithm essentially derives the same set of coercions as our procedure introduced at the end of section 8. However, due to our consistency requirement and the subtyping restriction on arrow types (and on type variables), the former may lead to a collection containing unrealizable coercions. It needs to be investigated whether it is decidable if a given expression is uniqueness typable, even though there need not be a`minimal' uniqueness type (see the discussion in Section 8).
Hankin and le M etayer (1994) present a general method for deriving type inference algorithms from (non-standard) type systems. The main application of this method is strictness analysis. It would be an interesting experiment to formulate uniqueness typing in this framework, and to compare the resulting type inference algorithm with the one described in the present paper.
In any case, we are planning to investigate whether our way of (non-standard) typing and type inference applies to other areas of static analysis, such as strictness analysis.
As has been mentioned before, our system is closely connected to substructural logics. A combined linear/full intuitionistic logic can be found in Benton (1994). The system described in this paper could be the rst step towards a`propositions as types/proofs as graphs' notion.