A Polymorphic Lambda-Calculus with Sized Higher-Order Types

Andreas Abel

June 19, 2006

2

Contents

1 Introduction 7 1.1 Why Termination? . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.2 Approaches to Termination . . . . . . . . . . . . . . . . . . . . . 9 1.3 Why Type-Based Termination Matters . . . . . . . . . . . . . . . 10 1.4 Informal Account of Type-Based Termination . . . . . . . . . . . 12

1.4.1 A Semantical Account of Type-Based Termination …. 12 1.4.2 From Semantics to Syntax . . . . . . . . . . . . . . . . . . 14

1.5 Contribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2 Sized Higher-Order Subtyping 19

2.1 Constructors and Polarized Kinds . . . . . . . . . . . . . . . . . 19 2.1.1 Polarities . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.1.2 Kinds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.1.3 Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.1.4 Kinding . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.1.5 Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

2.2 Higher-Order Subtyping . . . . . . . . . . . . . . . . . . . . . . . 28 2.3 Semantics and Soundness . . . . . . . . . . . . . . . . . . . . . . 29

2.3.1 Interpretation of Kinds . . . . . . . . . . . . . . . . . . . . 30 2.3.2 Semantics of Constructors . . . . . . . . . . . . . . . . . . 32

3 Type-Based Termination 37

3.1 Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.1.1 The Language . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.1.2 Typing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.1.3 Operational Semantics . . . . . . . . . . . . . . . . . . . . 41

3.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.2.1 Fibonacci Numbers . . . . . . . . . . . . . . . . . . . . . . 46 3.2.2 Co-Natural Numbers . . . . . . . . . . . . . . . . . . . . . 46 3.2.3 Some Pathological Cases . . . . . . . . . . . . . . . . . . . 46 3.2.4 Huffman Trees . . . . . . . . . . . . . . . . . . . . . . . . 47 3.2.5 Prime Numbers . . . . . . . . . . . . . . . . . . . . . . . . 50 3.2.6 Sorting by Merging . . . . . . . . . . . . . . . . . . . . . . 50 3.2.7 A Heterogeneous Data Type of Lambda Terms . . . . . . 52

3.2.8 Substitution for Finite and Infinite Lambda-Terms …. 54 3.3 Limits, Iteration, and Fixed-Points . . . . . . . . . . . . . . . . . 56

3.3.1 Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 3.3.2 Operator Iteration . . . . . . . . . . . . . . . . . . . . . . 57 3.3.3 Fixed points . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.3.4 Inductive and Coinductive Constructors . . . . . . . . . 60 3.3.5 Soundness of -Dropping . . . . . . . . . . . . . . . . . . 61

3.4 Semantical Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 3.4.1 Saturation . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 3.4.2 Admissible Types for Recursion . . . . . . . . . . . . . . 65 3.4.3 Refined Saturation . . . . . . . . . . . . . . . . . . . . . . 66 3.4.4 Admissible Types for Corecursion . . . . . . . . . . . . . 68 3.4.5 Lattice of Saturated Sets . . . . . . . . . . . . . . . . . . . 69

3.5 Soundness of Typing . . . . . . . . . . . . . . . . . . . . . . . . . 72 3.5.1 Admissible Types for Recursion, Syntactically . . . . . . 72 3.5.2 Admissible Types for Corecursion, Syntactically . . . . . 73 3.5.3 Soundness Proof . . . . . . . . . . . . . . . . . . . . . . . 74

3.6 Strong Normalization . . . . . . . . . . . . . . . . . . . . . . . . . 77 3.6.1 A Few Remarks on the Method . . . . . . . . . . . . . . . 77 3.6.2 Inductive Characterization . . . . . . . . . . . . . . . . . 78 3.6.3 Soundness of the Inductive Characterization . . . . . . . 81

4 Embeddings into F_{}85 4.1 An Iso-Recursive Version of F_{}. . . . . . . . . . . . . . . . . . . 85 4.2 Some Systems for Termination . . . . . . . . . . . . . . . . . . . 87 4.3 Some Systems For Productivity . . . . . . . . . . . . . . . . . . . 88 4.4 Iteration and Primitive Recursion . . . . . . . . . . . . . . . . . . 89

5 Continuity 93 5.1 On the Necessity of Criterion 2 . . . . . . . . . . . . . . . . . . . 94 5.2 Semi-Continuity . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 5.3 Type Constructors and Semi-Continuity . . . . . . . . . . . . . . 97

5.3.1 Function Space . . . . . . . . . . . . . . . . . . . . . . . . 99 5.3.2 Universal Quantification . . . . . . . . . . . . . . . . . . . 100 5.3.3 Coinductive Types . . . . . . . . . . . . . . . . . . . . . . 101 5.3.4 Inductive Types . . . . . . . . . . . . . . . . . . . . . . . . 103 5.3.5 Product and Sum Types . . . . . . . . . . . . . . . . . . . 107

5.4 A Kinding System for Semi-Continuity . . . . . . . . . . . . . . 107 5.5 Semantical Soundness of Continuity Derivations . . . . . . . . . 110 5.6 Type-Based Termination with Continuous Types . . . . . . . . . 114 5.7 Related and Future Work . . . . . . . . . . . . . . . . . . . . . . . 114 6 Examples 117

6.1 Breadth-First Tree Traversal . . . . . . . . . . . . . . . . . . . . . 117 6.2 Continuous Normalization of Infinite De Bruijn Terms . . . . . . 121 6.3 Normalization of Simply-Typed De Bruijn Terms . . . . . . . . . 123 6.4 Data Types with Higher-Order Parameters . . . . . . . . . . . . 126 6.5 Generic Programming . . . . . . . . . . . . . . . . . . . . . . . . 128 6.6 Impredicative Data Types . . . . . . . . . . . . . . . . . . . . . . 133 6.7 Inductive Proofs as Recursive Functions . . . . . . . . . . . . . . 134

7 Extensions 137 7.1 Mutual Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 7.2 More Admissible Types . . . . . . . . . . . . . . . . . . . . . . . 140

8 Conclusion 143

8.1 Related Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 8.1.1 Termination Proofs . . . . . . . . . . . . . . . . . . . . . . 144 8.1.2 Termination Checking . . . . . . . . . . . . . . . . . . . . 146 8.1.3 Sized Types . . . . . . . . . . . . . . . . . . . . . . . . . . 148

A Summary of F_{}151 A.1 Kinds and Constructors . . . . . . . . . . . . . . . . . . . . . . . 151 A.2 Terms, Typing and Reduction . . . . . . . . . . . . . . . . . . . . 153

A.2.1 Static Semantics . . . . . . . . . . . . . . . . . . . . . . . . 154 A.2.2 Admissible Recursion Types . . . . . . . . . . . . . . . . 154 A.2.3 Dynamic Semantics . . . . . . . . . . . . . . . . . . . . . . 155

A.3 Semi-Continuous Types for Recursion . . . . . . . . . . . . . . . 155

B Iso-Coinductive Constructors 157 B.1 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 B.2 Soundness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 B.3 Strong Normalization . . . . . . . . . . . . . . . . . . . . . . . . . 162

C Galois Connections 167

Bibliography 169

Index 183 6 CONTENTS

Chapter 1

Introduction

This thesis is on termination of computer programs. By termination we mean that the task given to a computer is processed in a certain amount of time, as opposed to taking infinitely long. Termination is the expected behavior of a computer; it does not make sense to wait infinitely long for its response. Some tasks take longer, e. g., booting, or calculating an airline schedule. Some take shorter, like, after a key press in a word processing program, displaying the new letter on the screen. Some take a variable time, like executing a command at the command prompt. Some tasks might indeed never end, like producing an even number greater or equal to four which is not the sum of two prime numbers. This task, call it goldbach, will run forever, if, as Goldbach conjectured,^{1} there exists no such number. Since the Goldbach conjecture is neither proven correct nor refuted,^{2} with our current knowledge we cannot judge whether goldbach will terminate or not.

Of course, we would like to know whether a computer program terminates before we start it. Otherwise we might sit there and wait for termination like one waits for a late bus, which will, by Murphy’s law, arrive exactly the minute after one has taken a taxi instead. The only way to tell whether a program will terminate without running it is to look at its internal structure, e. g., the sequence of instructions which make up the program. Compare this to a biologist who cuts up a frog in order to understand its behavior. Although a frog is magnitudes more complex in functionality^{3} than the biggest information system ever constructed, this analogy gives some intuition on what it means to grasp the meaning of a large computer program. In this light, the following negative solution to the Halteproblem, which is as old as the first computers, does not surprise:

There is no computer program which can take any (other) computer program and decide whether it terminates on some given input.

1The “Goldbach conjecture” in this form is actually due to Euler, see MathWorld [Wei05].

2As of today, the Goldbach conjecture has been confirmed for number up to 2 10^{17} [Wei05].

3The reader may excuse my comparison of a higher living being to something entirely mechanical like a computer program.

This theorem has a simple proof by contradiction: Suppose there is such a program . Then we can write a program which takes the code of some program as input, asks whether terminates on input , and enters an infinite loop if says “yes”. Now run on its own code. If terminates on , then says “yes”, hence does not terminate on . Otherwise, if does not terminate on , will say “no”, hence will terminate on . This is a contradiction,^{4} and thus, program cannot exist.

The negative solution to the Halteproblem destroys the hope of finding a automated termination checker which works on any kind of program. There are two escapes from this dilemma:

1. Use human intuition and reasoning to check termination.

2. Write a termination checker which works on a certain, restricted class of programs.

In practice, both methods are indispensable. In this thesis, we describe some class of terminating programs. But however big one may make the class, there will always be an interesting program whose termination cannot be verified completely automatically but requires at least some hint by a human who understands the program.

1.1 Why Termination?

But is termination really interesting? Would we not rather want to know how long the execution of a program takes? This is certainly true in real-time and embedded systems, like the hard- and software assisting the navigation of automobiles and planes. There, the system must react instantaneously, e. g., within milliseconds; termination is surely not sufficient. But there are other applications for termination:

1. Verified termination increases the chance that the program is correct. This argument has been put forward by Xi [Xi01] and has an analogy in static typing. Empirically, programs in strongly typed languages like Haskell and ML often work correctly already after they passed the compiler. The type checker spots many bugs, which would—in the absence of type checking— have surfaced one after another at runtime. In the same way, a termination checker could spot additional bugs which cannot be detected by the type checker. ^{5} 2. It is agreeable that compilers and program generators should terminate.

4The propositions = and = are contradictory even in intuitionistic logics.

5For example, I had written the following ML function.

fun fromto (from, to) = if from > to then [] else from :: fromto (from*1, to)

This program should output a list of integers starting with from and ending in to. The type inference of ML assigns it the expected type int * int -> int list, but upon execution, e. g., fromto (2, 641), it loops. It is supposed to return the empty list if from is greater or equal to to, and, otherwise, the element from plus the sequence from+1..to which is computed recursively. Here

However, to optimize the target program, they might have to partially evaluate the source code. Partial evaluation has to be restricted to these parts of the source which terminate; hence, termination has to be checked before evaluation. This is the motivation for Neil Jones’ research on termination. [JG02]

3. Program verification has been traditionally separated into two parts: proving partial correctness, meaning “if the program terminates then it satisfies its specification”, and proving termination. If termination can be established in a canonical way, a proof of partial correctness implies total correctness.

4. Interactive theorem provers with inductive types like Agda [CC99], Coq [BC04], Lego [Pol94] and Twelf [PS99] make use of the Curry-Howard isomorphism and allow proofs by induction to be written as recursive functions. But only terminating functions correspond to valid proofs, hence, termination is vital to maintain soundness of the proof system. This is the original motivation for my continuing research on termination and strong normalization.

In the following we consider systems—these could be programming languages, abstract calculi or logics—which have an expression language or a term language and a notion of computation.

1.2 Approaches to Termination

There are two fundamental kinds of systems: systems with partiality and total systems. In the first class, each expression has a meaning, even those expressions whose computation does not terminate. This class covers most programming languages, but also, e. g., the Logic of Computable Functions (LCF) and logics with undefinedness (Beeson [Bee04], Farmer [Far04]). The fact that an expression terminates (i. e., is defined) has to be proven in the logics.

In total systems, each valid expression is terminating. We can distinguish systems with or without recursion. For example, the simply-typed -calculus is a system without recursion. So is Girard’s [Gir72] System F^{}, but a limited form of recursion, iteration, is definable in it [GLT89, chap. 11] [BB85, RP93, PDM89, Geu92, Mat98, AMU05]. In HOL, even well-founded recursion is definable [Sli96]. Other systems have explicit recursion, which has to be tamed by some formalism to preserve termination of all expressions. Most notably, there are term rewriting systems (TRS). For TRS, many criteria have been developed for termination: polynomial interpretations, the recursive-path ordering, simplification orderings [Ste95], and dependency pairs [AG00]. These criteria are syntactical, as opposed to type-based; they work on untyped rewrite rules. Syntactical methods have also been applied to termination of logic programs and higher-order logic programs [Pie01]. The Fixpoint declaration of Coq, which introduces dependently-typed recursive functions, uses as of today a syntactical termination check, and Agda uses an implementation of the termination checker foetus [AA02].

we spot the bug: I had typed an asterix * instead of a plus + who are only a shift apart on a German keyboard. To locate this error in a bigger program took me more than an hour, since I had not expected the slip in such a simple function. A termination checker could have warned me that there might be a problem.

This thesis investigates type-based termination; by this we mean that termination checking is integrated with type checking: a program which passes the type-checker is guaranteed to terminate on all inputs.

1.3 Why Type-Based Termination Matters

I am convinced that the types paradigm is fruitful also for termination. The integration of termination checking into type checking has the following advantages.

Communication. The idea that each wellformed program fragment has a certain type seems still to be spreading in computing. Most firmly rooted is this view in strongly typed functional programming: in ML, each program must have a type which is inferable by the compiler. In practical software development, it has been fruitful to write down types as a documentation for the programmer. The type of a program gives an abstract idea which operation it implements, and this type, since checked by the compiler, is documentation which is always up-to-date. JAVA is a success story for a strongly typed language. Its design is quite contrary to ML, however: The type system is rather simple. It lacks higher-order functions, and subtyping is based on names, not on structure. The type of each variable has to be written down by the programmer and each exception a method can throw has to be declared, which makes JAVA a bit bureaucratic. A good compromise has been found in the design of Haskell: not each type must be inferable, but also not each type must be declared. Haskell’s type system not only features higher-order functions, higher-order and nested data types, and type classes, but also polymorphic recursion and higher-rank polymorphism with explicit quantification. Through programming practice, a Haskell programmer learns to think in a quite complex type language.

Once a programmer has learned to think in types, type-based termination of a program can be easily communicated to him. Once a program can be given a certain type, its termination ensues. The main thing a programmer needs to understand in order to master type-based termination as presented in this thesis, is that each data structure carries an upper bound for its size in its type, and that in a recursive call, this size must decrease.

Certification. Besides communicating termination to a human there is the problem of communicating termination to a machine, or more precisely, providing a machine-checkable certificate that a program terminates. For typebased termination, this question is already answered: a correct typing derivation for a program certifies its termination. The proof of this fact for a polymorphic functional language with higher-order data types, which we call F_{}, is the main technical contribution of this thesis.

A simple theoretical justification. Type-based termination can be reduced to a simple concept: induction on the size parameter. For polynomial datatypes like lists and binary search trees, natural numbers suffice as size indices, for infinitely branching trees, streams, and processes we need ordinal indices and transfinite induction. However, even in this case the programmer does not need ordinal notations and can continue to think of sizes as natural numbers.

Orthogonality. Type-based termination rests on the principle of sized data types and requires subtyping and restricted use of recursion. But these are the only parts of a purely functional language which are affected.^{6} Other language constructs, like higher-order functions, tuples and records, variants and disjoint sums, native types and operations like integers and reals can be added without having to change the termination machinery. All one has to do is to extend type checking and subtyping for the language—and this has to be done anyway. This is not true if termination checking is a separate module, e. g., some syntactic method. Then each extension of the language requires an extension of the termination checker, or even new research how termination checking can be extended to the new language constructs.

Robustness. A consequence of orthogonality is that the soundness of typebased termination is robust with regard to language extensions. As we show in this thesis, it is compatible with impredicative polymorphism. This does not hold for certain syntactic methods based on structural term orderings, as already pointed out by Coquand [Coq92] [AA02, page 3].

Higher-order functions. As another consequence of orthogonality, type-based termination plays its strength when applied to higher-order functions or higherrank polymorphism. Since sizes are integrated into types, one can specify that a higher-order argument of a function should be a non size-increasing operation, which can be safely applied to the recursion argument without destroying size information important for termination. In Section 6.5 we will see an example where typing with rank-2 polymorphism will be crucial for the termination of a generic merge function.

6It is well-known that higher-order references can simulate recursion, see, e. g., Xi [Xi02, section 4.6]. I/O and process communication can also be a source of non-termination, for instance, in form of deadlocks. Such impure language features are not treated in this thesis.

1.4 Informal Account of Type-Based Termination

What do we mean by type-based termination? In its broadest sense, the phrase refers to any type system which ensures that well-typed programs terminate. Very basic representatives of such systems are the simply or the polymorphically typed lambda-calculus. We want be more specific and refer only to languages with recursion (or, on the imperative side, loops), whose use is restricted by a type system such that it cannot introduce non-termination. Again, there are different ways to implement this idea. This thesis is about about type-based termination as coined by Barthe et al. [BFG^{+} 04], which builds on work by Mendler [Men87, Men91], Giménez [Gim98], and Amadio and Coupet-Grimal [ACG98], and has independently been invented by Hughes, Pareto, and Sabry [HPS96]. To simplify the following explanation of type-based termination, we will first refer to types in an informal, semantical fashion as sets of terms, but later we will be more precise and use types as syntactical objects, which are interpreted as sets of terms.

1.4.1 A Semantical Account of Type-Based Termination

General recursion can be implemented by adding a fixed-point combinator fix to a functional language based on a typed -calculus. This combinator is axiomatized as follows:

\frac{}{fix}  fix = (fix )

That means: If is a endo-function on type , then fix inhabits ; and fix behaves as (fix ). General recursion makes a language inconsistent as a logic, since every type is inhabited, and introduces non-termination, if the equation is read as a computation rule. (For both claims, take to be the identity function.) To maintain termination, the use of fix has to be restricted in some way.

Keeping only the axiom fix = (fix ), we make the following observation. Let and range over natural numbers, and ^{}be some type dependent on . Further let denote the all-type, i. e., each program is of this type without further requirements. Then the following typing rule for fix is admissible, i. e., provable using just the typing rules of -calculus:

0 = ^{}^{+1} for all

fix ^{}

The proof proceeds by induction on : If = 0, then fix = ^{0}. Now assume fix ^{}. Since ^{}^{+1} by assumption, (fix ) = fix +1 . Now the rough idea behind the work of Hughes, Pareto, and Sabry [HPS96] is: if _{ℕ} ^{}is “interesting” [Par00, p. 129], then fix has interesting properties, like termination or productivity. Interesting types are, e.g., ^{}= ℕ; then _{ℕ} ^{}= ℕ ℕ, and we can use the typing rule for fix to introduce total functions over natural numbers.

A typical application would be the following. Let ^{}denote the type of lists of natural numbers of length and ^{}= _{ℕ} ^{}the type of all natural number lists. Using the type ^{}:= ^{}^{}, we can define a recursive function which eliminates all zeros from a list. Since ^{0} is empty, ^{0} is isomorphic to the all-type (under the standard semantics of the function type, = for all ). Using pattern matching notation we can define the following functional .

(( ^{}^{}) ^{+1}  ^{})
:= filter0 match with
nil  nil
cons 0  filter0
cons  cons (filter0 )

Then filter0 := fix _{}( ^{}^{}) is the desired filtering function which can be applied to lists of any length. Of course, we need to make sure is welltyped. For example, if the input list = cons ^{+1} has length + 1, then the length of the tail is certainly below , which implies that the recursive call filter0 is well-typed and, thus, justified.

Lists are a special case of an inductive type; list of bounded length are a special case of a sized inductive type. In general, if is an isotone operator on term sets, then ^{}denotes the inductive type which is the least fixed point of . In case of lists of natural numbers, we have ( ) = nil cons ℕ and . A sized inductive type is obtained by ordinal iteration of :

0  =  (the empty type)
+1  = ( ^{})
=  _{}^{}( limit ordinal)

It is easy to see that ^{}, for the list-specific given above, contains exactly the lists of length , hence ^{}= ^{}. Since all lists have finite length, the least fixed point ^{}= _{ℕ} ^{}= _{}^{}= ^{}is reached at the smallest infinite ordinal . However, there are inductive types with a higher closure ordinal, for example, the second number class with the generating operator ( ) = ozero osucc olim ℕ . If Ord^{}denotes the -iterate of this operator, then the constructors have the following types:

ozero  _{}Ord^{+1}
osucc  _{}(Ord^{}Ord^{+1} )
olim  _{}((ℕ Ord^{}) Ord^{+1} )

If ℕ Ord^{}is given by (0) = ozero and ( + 1) = osucc( ( )), then olim Ord^{+1} appears for the first time at the iterate + 1, hence, there are terms of transfinite height in the second number class.

Consequently, a recursive function over elements of type Ord must treat also transfinite iterates Ord^{}for . To account for the limit iterates, we extend our introduction rule for recursive functions as follows:

0 =  ^{}^{+1} for all  _{}^{}^{}for all limits 0

fix ^{}

Again, this rule is provable, this time by transfinite induction on : Base and step case work as before, for the limit case we need to show fix ^{}under the induction hypothesis fix ^{}for all . But exactly this is given by the new assumption. Now, if we summarize the two conditions on the type ,

1. ^{0} = , and

2. _{}^{}^{}for all limits ,

into the predicate adm, we get a rule which looks quite similar to the rule for general recursion:

\frac{^{}^{+1} for all}{fix ^{}}adm

1.4.2 From Semantics to Syntax

The goal of this thesis is to turn the semantical recursion rule into syntax, i. e., into a typing rule, and show that all well-typed programs are strongly normalizing. If we take a close look at the syntactical components of the semantical types we used in the constructors and the recursion rule in the last section, we find the following elements:

• types indexed by ordinal variables , their successor + 1 or the closure ordinal ,

• function types ,

• infimum _{}of a family of types indexed by , and

• a condition adm on types for recursion.

Surprisingly, there are only these few elements and they can be turned into syntax directly. To the type language of a simple or polymorphic lambda-calculus we add a language of size expressions : ord composed from size variables , successor + 1, and , which denotes a large ordinal at which the iteration processes for all inductive types of the system close. The infimum _{}is expressed by size polymorphism . Finally, we formulate a syntactic criterion on types adm which entails the semantic one. This leads to the syntactic recursion rule

\frac{:  ^{}^{+1}  : ord}{fix : ^{}}adm

There is natural order on size expressions induced by + 1 and . Since the approximation stages of an inductive type are ordered ascendingly by inclusion, we get a natural subtype relation ^{}^{}for .

The first part of this thesis deals with the subtyping induced by sizes in the presence of co- and contravariant type constructors.

The distinguished feature of our approach is that we speak about ordinal indices in our type system without requiring an ordinal notation system, like Cantor normal forms. The user can think of sizes as natural numbers instead of ordinals without making mistakes.

1.5 Contribution

This thesis is not the first one on typed-based termination. Pareto [Par00] has explored this paradigm in the area of functional programming. He developed Synchronous Haskell, the core of a functional language with type-based termination and productivity checking, which is summarized in Hughes et al. [HPS96]. He proves the soundness of his system by non-standard denotational semantics, interpreting types as upward-closed sets of values. Pareto considers only ordinals up to , and, thus only inductive data types without embedded function spaces, excluding the type Ord.

Frade’s thesis [Fra03] introduces , an extension of -calculus with MLpolymorphism by sized inductive types, which is summarized in Barthe et al. [BFG^{+} 04]. She does treat inductive types with embedded function spaces and she proves subject reduction and strong normalization for .

Our contribution, in relation to the above theses and to other systems of type-based termination, is progress in the following areas:

Higher-order inductive types. Our inductive types can contain embedded function spaces and, at the same time, be of higher kind. Therefore, neither iteration to the first infinite ordinal, , as in Pareto’s case, nor to the first uncountable ordinal, Ω, as in Frade’s case seems sufficient. The upper bound for our closure ordinal is the th uncountable.

A theory of semi-continuous types. Frade restricts result types of recursive functions to be monotone in their size argument. Pareto is more liberal, allowing types which are, in his terminology, -undershooting. He gives some criteria how to classify such admissible types, but in a rather ad-hoc manner. We show that similar types are admissible in our semantics where types are sets of strongly normalizing terms, which is quite distinct from his domaintheoretic semantics. However, since we allow infinite branching, inductive types will fall in a different class in our case. We put his ad-hoc analysis of admissible types on a more solid basis by classifying types as upper or lower semi-continuous, which are standard concepts in analysis. Furthermore, we cast or results in kinding rules for semi-continuous types, thus, mechanizing the quest for admissible types.

Heterogeneous data types. We are the first to consider typed-based termination for heterogeneous or nested data types. Heterogeneous data types can be viewed as fixed points of type constructors of a higher kind, such that the fixed point is not a type but a type constructor. Such heterogeneous types have been analyzed in the mathematics of program construction and in Haskell by Hinze [Hin98, Hin99, Hin00a, Hin00b, Hin01] Bird and Meertens [BM98], Bird and Paterson [BP99a], Martin and Gibbons [MG01] and Bayley [MGB04] and in the context of System F^{}by Pierce, Dietzen, and Michaylov [PDM89], Matthes [Mat01], Matthes and myself [AM03, AM04], and with Uustalu [AMU03, AMU05]. Note that heterogeneous data types are not a special case of inductive families [Dyb94].

Equi-(co)inductive types. In contrast to many predecessors [Geu92, Alt93, Mat98, Alt99, AA00, BJO01, BFG^{+} 04] of our work, we do not use the common iso-recursive approach to (co)inductive types, but the equi-recursive one, hence, we consider equi-(co)inductive types. For example, take the Haskell data type of binary trees:

    data BT a = Leaf
              | Node (BT a) a (BT a)

The finite binary trees can be modeled by an inductive type. Using equi-inductive types, one can decompose a data type into recursion and a labeled sum. For this example, the decomposition would read

BTF :
BTF :=  Leaf 1 + Node (  )
BT :
BT :=  (BTF )

where 1 is the unit type, _{1} _{1} + + _{}_{}is the labeled sum of the types 1, and is the least fixed-point combinator, fulfilling the type equation = ( ). The constructors of the labeled sum can be reused directly as constructors for binary trees.

Iso-inductive types, however, fold and unfold noisily: Special terms in : ( ) and out : ( ) construct and destruct iso-inductive types, and is only isomorphic to ( ) (hence, the name). The constructors for binary trees now read in Leaf and in Node. This seems less direct and lessintuitive than the equi-inductive approach. On the other hand, the metatheory of iso-inductive types is simpler, because we know that each canonical inhabitant of an inductive type is of the form in .

In this thesis, we analyze the more challenging metatheory of equi-inductive and -coinductive types. Especially the combination of equi-induction and equicoinduction will have some unpleasant effects when it comes to a strongly normalizing reduction system. Anyhow, we fight our way through, but if you want to avoid hardship, stick to iso-coinductive types!

A unified language for types and size expressions. In contrast to previous work on sized types, we unify the languages of sizes and types by introducing a new base kind ord of sizes into F^{}. This enables us to give precise types to polymorphic higher-order functions such as foldr. In our calculus, it can be given the type

foldr :  :  :ord ^{+}

( :ord ( + 1)) ( :ord ( + 1)) ( :ord List^{})

By giving size information to polymorphic combinators such as foldr, even functions built-up from these combinators can have sized types. This is a novelty with regard to existing systems of type-based termination, like Barthe et al. [BFG^{+} 04], Hughes et al. [HPS96], and Xi [Xi02].

18 CHAPTER 1. INTRODUCTION

Sized Higher-Order Subtyping

In this chapter, we define the kind and constructor level of F_{}, the higher-order polymorphic -calculus with sized types. We present rules for equality and subtyping and show their soundness through a set-theoretic model.

2.1 Constructors and Polarized Kinds

The higher-order polymorphic lambda-calculus introduces the notion of type constructor or just constructor. In the first intuition, it is a function which takes one or several types and produces a type, a so called type transformer. For example, the Cartesian product is a constructor: It takes two types and and produces the product type whose canonical elements are pairs ( ) of terms : and : . The notion of constructor is then taken to higher orders: A type is a constructor, a function on constructors is a constructor itself.

2.1.1 Polarities

We aim to distinguish constructors with regard to their monotonicity or variance. For instance, the product constructor is isotone or covariant in both of its arguments. If one enlarges the type or , more terms inhabit . The opposite behavior is called antitone or contravariant. Finally, a function might not exhibit a uniform behavior, it might grow or shrink with its argument, or we just do not know how behaves. This is the general case, we call it nonvariant. Each of the behaviors is called a polarity and abbreviated by one of the following symbols:

Pol  ::=  non-variant
+  covariant
contravariant

The polarities are related: Since “non-variant” just means we do not have any information about the function, and we can forget our knowledge, each function is non-variant. The inclusion order between the three sets of co-, contra-, and non-variant functions induces a partial information order on Pol. The smaller a set is, the more information it carries. Hence , and for all . We visualize the partial order on Pol as follows:

[figure: +; ; ]

Remark 2.1 In notation and order of polarities we follow Duggan and Compagnoni [DC99]. Detailed studies of polarized subtyping have been performed by Steffen [Ste98]. He uses a different notation and considers the dual ordering.

Polarity of composed functions. Let be two functions such that the composition is well-defined. If has polarity and has polarity , we denote the polarity of the composed function by . It is clear that polarity composition is isotone: if one gets more information about or , certainly one cannot have less information about . Then, if one of the functions is non-variant, the same holds for the composition. In the remaining cases, the composition is covariant if and have the same variance, otherwise it is contravariant. We obtain the following multiplication table:

\begin{aligned}& & + & \\ & & & \\ + & & + & \\ & & & + \end{aligned}

Polarity composition, as function composition, is associative. It is even commutative, but not a priori, since function composition is not commutative.

Remark 2.2 Instead of polarities we could take signs 0 +1 1 with ordinary multiplication and the non-standard order ^{}= ^{} .

Remark 2.3 ( polarity) Steffen [Ste98] and Duggan and Compagnoni [DC99] include a fourth polarity, called in second loc. cit., which indicates that a function is invariant or constant. The symbol “ ” is justified since a constant function is both isotone and antitone. The ordering on polarities is extended by for all . For our purposes, is not interesting.

2.1.2 Kinds

Constructors are classified by their kind, i. e., as types, functions on types, functions on such functions etc. Extending the kinds of F^{}, we introduce a second base kind ord. Constructors of this kind are syntactic representations of ordinals.

Kind  ::=  types
ord  ordinals
1  _{2}  -variant constructor transformers

A constructor of kind _{1} _{2} is a -variant function which maps constructors of kind _{1} to constructors of kind _{2}. We introduce the following abbreviations:

for _{1} _{1}  _{}_{}^{}
^{}^{}for  ^{}and
^{}^{}for ^{}

Using the vector notation (first line) for kinds includes the assumption = = . Our base kinds, sometimes denoted by 0, are and ord. It is clear that every kind can be written in vector notation ^{}with potentially empty vectors and . Especially, every kind can be written in this vector notation such that ^{}is a base kind.

Pure kinds are kinds which do not mention base kind “ord”. These are the kinds of Steffen’s polarized F_{}^{}and given by the following grammar.

::= _{}_{}^{}

The rank rk( ) ℕ of a kind is defined recursively as follows:

rk( 0)  = 0  0  ord
rk(  ^{}) = max(rk( ) + 1 rk( ^{}))

With := we have rk( 0) = max 1 + rk( _{}) 1 . If = 0, then even rk( 0) = 1 + max rk( _{}) 1 .

2.1.3 Constructors

Constructors are given by the following Curry-style type-level lambda-calculus with some constants. The meta-variable ranges over a countably infinite set TyVar of constructor variables.

::=

In most cases, we will use , , and for constructors of arbitrary kind, and for types (kind ) and and for ordinal expressions, i. e., constructors of kind ord. Ordinal variables will be denoted by and whereas constructor variables of arbitrary kind will be denoted by , and . As usual, binds variable in . We identify constructors under -equivalence, i. e., under renaming of bound variables. FV( ) shall denote the set of free variables of constructor .

Signature. The constructor constants are taken from a fixed signature Σ which contains at least the following constants together with their kinding.

: ^{}^{+}  function space
: ( ^{}) ^{+}  quantification
: ord ^{+} ( _{}^{+} _{}) ^{+} _{}inductive constructors
: ord ^{}( _{}^{+} _{}) ^{+} _{}coinductive constructors
s : ord ^{+} ord  successor of ordinal
: ord  infinity ordinal

We often denote one of _{_{}}, _{_{}}as _{_{}}. Note that the indices _{}of these constants are pure kinds. Otherwise, we could define ordinals as least or greatest fixed points of some ordinal function. When clear from the context of discourse, we omit the indices of inductive and coinductive constructors and quantification. We introduce the following notations:

:  for _{}
for
:  for _{}
for  and
_{}^{}for _{}

The last notation is generalized to any constructor : ord ^{}on ordinals: We allow the notation ^{}for application .

Remark 2.4 In the above signature, the only closed constructors of kind ord are of the form s (s ( )) for a finite number of successors s. Semantically, all these ordinals are equal to . Hughes, Pareto, and Sabry [HPS96] add a constant 0 : ord denoting the ordinal zero, in order to get a more precise typing for constant objects of inductive type. Our syntax of ordinals is equivalent to the stage expressions of Barthe et al. [BFG^{+} 04].

Example 2.5 (Impredicative encodings) Constructors for Cartesian product , disjoint sum +, and existential type can be defined by the following impredicative encodings.

\begin{aligned} & : & ^{+} ^{+} \\  & := & : (  ) \\ + & : & ^{+} ^{+} \\ + & := & : ( ) ( ) \\ _{} & : & ( ^{}) ^{+} \\ _{} & := & : ( :  ) \end{aligned}

We will use and + in infix notation and right associative. Later we will present a method to check that these definitions are well-kinded and do possess their claimed variance.

Example 2.6 (Types with finitely many inhabitants) We define 0 := : , 1 := : , and Bool := 2 := 1 + 1. It is clear how we could go on and define 3, 4, etc.

Example 2.7 (Regular data types) In the following examples, we define some inductive types. They are called regular data types because all of them are fixed points of a type transformer ( _{}). The first type represents natural numbers in unary encoding, the second type polymorphic lists, the third one trees branching over type with node-labels of type , and the fourth one Brouwer ordinals.

Nat : ord ^{+}
Nat :=  ^{}1 +
List : ord ^{+} ^{+}
List :=  ^{}1 +
Tree := ord ^{+} ^{}^{+}
Tree :=  ^{}1 + ( )
Ord := ord ^{+}
Ord :=  ^{}1 + + (Nat^{})

The first argument of the constructors in this example is an ordinal number describing the bound for the height of elements, when viewed as trees, in this data type. The height of a tree is defined as one plus the least upper bound of the heights of its immediate subtrees. There are no trees of height zero. Natural numbers and lists are linear trees, hence, their height is equal to one plus the length of the list resp. the unary encoding of the natural number. For finitely branching trees, the height is a finite ordinal, but for infinitely branching trees, it might be infinite. For instance, consider a Nat^{}branching tree whose th immediate subtree has height . Then the height of the whole tree is + 1.

Types like Nat^{}and List^{}are called sized types since they carry a bound for the size of their inhabitants. Closely related sized type systems are (Barthe et al. [BFG^{+} 04]) and the one of Hughes, Pareto, and Sabry [HPS96]. The latter one rejects infinitely branching trees and, hence, considers only ordinals up to .

Example 2.8 (Non-regular data types) The following heterogeneous or nested data types are well-known from the literature on functional programming. Elements of PList^{}are power lists [BGJ00], i. e., list of length 2^{}for some , or, alternatively, perfect trees [Hin99], i. e., perfectly balanced leaf-labeled binary trees. The second type Bush^{}, bushy lists, models finite maps from unlabeled binary trees of height into [Alt01, Hin00b]. An the third type, Lam^{}, is inhabited by de Bruijn representations of untyped lambda terms of height with free variables in [BP99b, AR99].

PList : ord ^{+} ^{+}
PList :=  ^{}+ ( )
Bush : ord ^{+} ^{+}
Bush :=  ^{}1 +  ( )
Lam : ord ^{+} ^{+}
Lam :=  ^{}+  + (1 + )

Example 2.9 (Coinductive types) The prime example of a coinductive type, Stream^{}, contains infinite lists of elements in that are at least defined up to depth . In other words, retrieving the th element of a stream is guaranteed to succeed if .

Stream : ord ^{}^{+}
Stream :=  ^{}

2.1.4 Kinding

In this section, we present rules of kinding, i. e., assigning kinds to constructors. The rules extend the kinding rules of F^{}by the treatment of polarities.

Positive and negative occurrence. In the simply typed lambda-calculus and in System F there are simple syntactic definitions of positive and negative occurrence of type variables in types. Let be a type expression, viewed as a tree. A type variable is said to occur positively in if the path from the root to takes the left branch of an -node an even number of times; otherwise, occurs negatively. This simple syntactic criterion does not scale to a higher-order type system like F_{}, the system under consideration, hence we will define positivity and negativity via the kinding judgement, following previous work [AM04]. Nevertheless, the simple criterion might serve the reader as a first intuition.

Polarized contexts. A polarized context Δ fixes a polarity and a kind for each free variable of a constructor . If = + , then may only appear positively in ; this ensures that is an isotone function. Similarly, if = , then may only occur negatively, and if = , then may appear in both positive and negative positions.

PCxt Δ ::=  empty context
Δ :  extended context ( dom(Δ))

The domain dom(Δ) is the set of constructor variables Δ mentions. Naturally, each variable can appear in the context only once.

Ordering on contexts. We say context Δ^{}is more liberal than context Δ, written Δ^{}Δ, iff

( : ) Δ implies ( : ^{}) Δ^{}for some ^{}

In particular, Δ^{}may declare more variables than Δ and assign weaker polarities to them. The intuition is that all constructors which are well-kinded in Δ are also well-kinded in a more permissive context Δ^{}.

The empty context is the most strict context since Δ for any Δ. In contrast, there is no most liberal context.

Application of polarities to contexts. We define application Δ of a polarity to a polarized context Δ. It composes with every polarity assigned to a variable in Δ. It is easy to see that + Δ = Δ and ( Δ) = ( )Δ since + is the neutral element of Pol and polarity composition is associative, hence, Δ = Δ and Δ = Δ. The last operation removes all polarity information from a context, making it isomorphic to a classical kinding context for System F^{}, except for the polarities within types. Application inherits monotonicity from polarity composition: Δ ^{}Δ^{}if ^{}and Δ Δ^{}. An instance of monotonicity is the law Δ Δ^{}Δ Δ^{}.

Kinding. We will introduce a judgement Δ : which combines the usual notions of well-kindedness and positive and negative occurrences of type variables. A candidate for the application rule is

\frac{Δ  :  ^{}Δ^{}:}{Δ  : ^{}}Δ Δ^{}

The side condition is motivated by polarity composition. Consider the case that FV( ). If is viewed as a function of , then is the composition of and . Now if is -variant in , then is -variant in . This means that all -variant variables of Δ^{}must appear in Δ with a polarity of at most . Now if FV( ), it could be that it is actually declared in Δ with a polarity smaller than . Also, variables which are not free in are not affected by the application , hence they can carry the same polarity in as in . Together this motivates the condition Δ Δ^{}.

To eliminate the side condition from the application rule, we need a function which computes the most liberal context Δ^{}from Δ which satisfies both conditions.

Inverse application of polarities. We are looking for an inverse to application, ^{1} Δ, which should be the least Δ^{}such that Δ Δ^{}. If such an inverse application exists, it is monotone and forms a Galois connection with the application operation, i. e.,

1 Δ Δ^{}Δ Δ^{} This inverse indeed exists and obeys the equations + ^{1} Δ = Δ, ^{1} Δ = Δ, and ^{1} Δ = : Δ = , respectively.^{1} In all three cases, ^{1} ( Δ) Δ, and the side condition Δ ( ^{1} Δ) holds.

Kinding (continued). Now we are ready to introduce a judgement Δ : inductively by the following rules:

kind-c \frac{: Σ}{Δ :}  kind-var \frac{:  Δ  +}{Δ :}

kind-abs \frac{Δ :  : ^{}}{Δ  :  ^{}}

kind-app \frac{Δ  :  ^{}^{1} Δ :}{Δ  : ^{}}

To understand these rules, it is useful to think of in the context Δ = : as a function ( ). The judgement Δ : should be valid if both has kind and grows (weakly) whenever the positive arguments to grow, the negative shrink and the non-variant stay fixed.

Hence, rule kind-var can only allow non-negative variables to be fetched from the context. In contrast, constants may appear with any polarity (kind-c ). The rule kind-abs for abstraction is suggestive.

Explanation of the application rule. Because of its central role, rule kind-app is given again a very detailed explanation. First, observe that whenever grows (with fixed ), then also the application grows. Hence, the polarity of the variables in is the same as those in . To see how the application behaves if we modify , let us consider the cases = + separately:

kind-app+ \frac{Δ  : +  ^{}Δ :}{Δ  : ^{}}

In the first case, is a monotone function, hence whenever its argument grows, the application grows as well. Hence, the polarity of the variables in matches the polarity of the variables in .

kind-app \frac{Δ  :  ^{}Δ :}{Δ  : ^{}}

If is antitone, the application will grow if shrinks. Hence, the polarity of the variables in must be opposite ( Δ) to the one of the variables in the application (Δ). Imagine a variable appearing negatively in . If it grows, will shrink, hence will grow. Therefore appears positively in the application.

1Unlike for integers, reversing the sign does not reverse the inequality: We have Δ Δ^{} Δ Δ^{}.

kind-app \frac{Δ  :  ^{}^{1} Δ :}{Δ  : ^{}}

In the non-variant case, we do not know how behaves if we modify its argument. To satisfy our informal semantics, needs to grow if we grow the variables declared in Δ to be positive, shrink the negative variables, and leave the non-variant ones fixed. If one of the positive or negative variables appeared in , the argument to would change which would result in an unpredictable shift of the value of . If we want to verify that grows we need to ensure that no positive or negative variables occur in . This is done by erasing all non-variant variables from the context through the operation ^{1} Δ.

Example 2.10 (Derived rules for function space and quantification) The following rules are derivable:

\frac{Δ :  Δ :}{Δ  :}  \frac{Δ :  :}{Δ  : :}

2.1.5 Equality

Type constructors are considered equal modulo . Further, the successor of the closure ordinal is considered equal to the closure ordinal. The judgement Δ = ^{}: is defined inductively by the following rules:

Computation axioms.

eq- \frac{Δ :  : ^{}^{1} Δ :}{Δ ( ) = [ ] : ^{}}

eq- \frac{Δ  :  ^{}}{Δ (  ) = :  ^{}}

eq- \overline{Δ s = : ord}

Congruence rules. In rule eq-app we have to modify the polarities of the variables in and ^{}in the same way as in the application rule of the kinding judgement: We inverse-apply to the context Δ.

eq-c \frac{: Σ}{Δ = :}  eq-var \frac{:  Δ  +}{Δ = :}

eq- \frac{Δ :  = ^{}: ^{}}{Δ  = ^{}:  ^{}}

eq-app \frac{Δ  = ^{}:  ^{}^{1} Δ = ^{}:}{Δ  = ^{}^{}: ^{}}

Symmetry and transitivity.

eq-sym \frac{Δ  = ^{}:}{Δ ^{}= :}

eq-trans \frac{Δ _{1} = _{2} :  Δ _{2} = _{3} :}{Δ _{1} = _{3} :}

The rule for reflexivity is admissible thanks to the congruence rules:

Lemma 2.11 (Reflexivity) If :: Δ  : then Δ  = : .

Proof. By induction on . □

Lemma 2.12 (Validity) If :: Δ  = ^{}: then Δ  : and Δ ^{}: .

Proof. By induction on . □

Together, Δ  : holds if and only if Δ  = : .

Remark 2.13 The rules for kinding and equality are in essence those used in previous work of the author with Matthes [AM04], extended by eq- . Note that in loc. cit., the inverse application ^{1} Δ of a polarity to a context was written Δ.

2.2 Higher-Order Subtyping

In this section, we specify subtyping for constructors of polarized kinds. The rules are inspired by Steffen [Ste98].

Reflexivity, transitivity and antisymmetry. These three properties make subtyping a partial order on constructors of the same kind.

leq-refl \frac{Δ  = ^{}:}{Δ  ^{}:}

leq-trans \frac{Δ _{1}  _{2} :  Δ _{2}  _{3} :}{Δ _{1}  _{3} :}

leq-antisym \frac{Δ  ^{}:  Δ ^{}:}{Δ  = ^{}:}

The reflexivity rule includes the subtyping axioms for variables and constants as special cases. Reflexivity and transitivity together ensure that subtyping is compatible with equality. The antisymmetry rule potentially enlarges our notion of equality.

Abstraction.

leq- \frac{Δ :  ^{}: ^{}}{Δ  ^{}:  ^{}}

Application. There are two kinds of congruence rules for application: one kind states that if functions and ^{}are in the subtyping relation, so are their values and ^{}at a certain argument .

leq-app \frac{Δ  ^{}:  ^{}^{1} Δ :}{Δ  ^{}: ^{}}

The other kind of rules concern the opposite case: If is a function and two arguments and ^{}are in a subtyping relation, so are the values and ^{} of the function at these arguments. However, such a relation can only exist if is either covariant or contravariant.

leq-app+ \frac{Δ  : +  ^{}Δ  ^{}:}{Δ  ^{}: ^{}}

leq-app \frac{Δ  :  ^{}Δ ^{}:}{Δ  ^{}: ^{}}

What about a comparable rule for non-variant constructors? It is derivable:

{Δ  :  ^{}{^{1} Δ  ^{}:  ^{1} Δ ^{}: \atop ^{1} Δ = ^{}:} \atop Δ  = ^{}: ^{}} ; Δ  ^{}: ^{}

Successor and infinity.

leq-s-r \frac{Δ : ord}{Δ  s : ord}  leq- \frac{Δ : ord}{Δ  : ord}

Lemma 2.14 (Validity II) If :: Δ  ^{}: then Δ  : and Δ ^{}: .

Proof. By induction on , using validity of equality (Lemma 2.12) in case of leq-refl . □

2.3 Semantics and Soundness

In this section we give a semantics to kinds and constructors and show soundness of kinding, constructor equality and subtyping.

2.3.1 Interpretation of Kinds

Constructors of kind will be interpreted as operators which live in the denotation [[ ]]of their kinds. Each kind will be interpreted as a poset (partially ordered set) ([[ ]] ^{}), which is even a complete lattice in each case.

Interpretation of base kind . For the moment, we assume a complete lattice [[ ]]of countable sets [[ ]]ordered by inclusion, with a maximal set ^{} [[ ]]such that ^{}for all [[ ]]. Later, we will let [[ ]]be the collection of all saturated sets SN where ^{}= SN is the set of strongly normalizing terms. So, let

[[ ]] :  complete lattice of sets
:  ^{}
⨅^{}𝔄 :=  𝔄 (where 𝔄 [[ ]])

By assumption, the poset ([[ ]] ^{}) is closed under infima, i. e., for a non-empty subset 𝔄 [[ ]]the infimum ⨅^{}𝔄 [[ ]]exists and is equal to the intersection 𝔄. Intersection can be extended to empty collections by letting ⨅^{}= ^{}. Once empty intersections are defined, we can define arbitrary suprema by 𝔄 := ⨅^{}[[ ]] ^{}for all 𝔄 . Note that we do not require that the supremum is the union of sets; it might actually be something bigger. On the set [[ ]]we assume a binary operation “ ” (function space construction) such that ^{}^{}^{}if ^{}^{}and ^{}^{}.

Interpretation of base kind ord. Constructors “ ” of kind ord denote settheoretic ordinals in our semantics. We choose an initial segment [0; ^{ord}] =: [[ord]]of the ordinals for the interpretation of ord. At the moment we leave it open which ordinal ^{ord} denotes; we will fill it in later.

[[ord]] :=  ^{ord} + 1
ord ^{}:  ^{}

Notation. We introduce a notation ^{}^{}for polarized inclusion and the notion ^{}^{}[[ ]]which expresses polarized inclusion for two operators plus the fact that both are in the set [[ ]].

\begin{aligned}^{+} ^{} & : & ^{}^{} \\ ^{}^{} & : & ^{}^{} \\ ^{}^{} & : & ^{}^{}and ^{}^{} \\ ^{}^{}[[ ]] & : & ^{}[[ ]]and ^{}^{} \\ ^{}[[ ]] & : & ^{+} ^{}[[ ]] \end{aligned}

Interpretation of function kinds. Semantically, a constructor of kind is a covariant ( = + ), contravariant ( = ) or non-variant ( = ) operator. We define the posets ([[ ]] ^{}) for higher kinds by induction on .

[[  ^{}]] :=  [[ ]] [[ ^{}]] ( ) ( ^{}) [[ ^{}]]

for all ^{}^{}[[ ]]

:  ( ) ^{^{}}^{}( ) for all  [[ ]]

Lemma 2.15 (Partial order) For each kind , the relation ^{}denotes a partial order on [[ ]].

Proof. By induction on . For base kinds 0 ord reflexivity, transitivity and antisymmetry hold by definition. To prove transitivity for higher kinds, assume = _{1} _{2} and _{1} _{2} [[ ]], _{2} _{3} [[ ]], and an arbitrary [[ _{1}]]. Since by ind. hyp. ^{_{1}} , we have _{1}( ) _{2}( ) [[ _{2}]]and _{2}( ) 3( ) [[ _{2}]]by definition. By induction hypothesis _{1}( ) ^{_{2}} _{3}( ), and since was arbitrary _{1} ^{_{1} _{2}} _{3}. Reflexivity and antisymmetry are proven analogously. □

Pointwise infima, upper bounds and suprema. For higher kinds, we define inductively pointwise infimum and maximal element as follows.

\begin{matrix}⨅^{^{}}𝔉 &  & [[ ]] [[ ^{}]] for 𝔉 [[  ^{}]] \\ (⨅^{^{}}𝔉)( ) & := & ⨅^{^{}}( )  𝔉 \\ ^{^{}} &  & [[  ^{}]] \\ ^{^{}}( ) & := & ^{^{}} \end{matrix}

A simple proof by induction on shows that ^{}is really the maximal element of [[ ]]for any kind . Extending the observations for kind , we can now define empty infima and arbitrary suprema for all kinds.

\begin{aligned}⨅^{} & := & ^{} \\ ^{}𝔉 & := & ⨅^{}[[ ]]  ^{}for all  𝔉 \end{aligned}

Lemma 2.16 (Supremum is pointwise) ( ^{^{}}𝔉)( ) = ^{^{}}( ) 𝔉 .

The posets [[ ]]now are equipped with everything required for complete lattices.

Lemma 2.17 (Complete lattice) For all kinds , the triple ([[ ]] ⨅^{}^{}) forms a complete lattice.

Proof. We only need to show that ⨅^{}𝔉 [[ ]]is the well-defined greatest lower bound for 𝔉 [[ ]]by induction on . For base kinds, there is nothing to prove.

1. Well-definedness: Show ⨅^{^{}}𝔉 [[ ^{}]]. Assume ^{}^{}[[ ]]. Then ( ) ( ^{}) [[ ^{}]]for all 𝔉. Since the infimum is welldefined at kind ^{}by induction hypothesis, this entails

(⨅^{^{}}𝔉)( ) = ⨅^{^{}}( )  𝔉 ^{^{}}
⨅^{^{}}( ^{})  𝔉 = (⨅^{^{}}𝔉)( ^{})

2. Lower bound: Show ⨅^{^{}}𝔉 ^{^{}}for all 𝔉. Assume [[ ]] arbitrary. Since by induction hypothesis, ⨅^{^{}}is a lower bound,

(⨅^{^{}}𝔉)( ) = ⨅^{^{}}( ) 𝔉 ^{^{}}( )

for any 𝔉.

3. Greatest lower bound: Let  [[  ^{}]]for all  𝔉. Show

⨅^{^{}}𝔉. For [[ ]] arbitrary, ( ) ^{^{}}( ) for any 𝔉 by assumption. Since by induction hypothesis ⨅^{^{}}is a greatest lower bound,

( ) ^{^{}}⨅^{^{}}( ) 𝔉 = (⨅^{^{}}𝔉)( )
□

2.3.2 Semantics of Constructors

In the following we develop a semantics of constructors through their derivations of well-kindedness. This indirect path is necessary since the constructors are domain-free. E. g., it is not determined which function is denoted by the constructor ; it could be the identity function on [[ ]]for any kind . In joint work with Ralph Matthes I have investigated polarized kinding and semantics of Church-style constructors [AM04]. There, :+ denotes exactly one set-theoretic function: the identity on [[ ]]. The following development resembles closely the cited work, however, we take the detour via derivations here.

Sound valuations. Let be a mapping from constructor variables to sets. We say [[Δ]]if ( ) [[ ]]for all ( : ) Δ. A partial order on valuations is established as follows:

[[Δ]] : ( ) ^{}^{}( ) [[ ]]for all ( : ) Δ

We use ^{}for and ^{}for =, and ^{+} as synonym for . It is clear that [[Δ]]iff ( ) ^{}^{}( ) [[ ]]for all ( : ) Δ.

Lemma 2.18 If ^{}[[Δ]], then ^{}^{}[[ ^{1} Δ]].

Proof. By cases on . Interesting is only case = . Assume : [[ ^{1} Δ]], which is only possible if = and : [[Δ]]. We have to show ( ) ^{} ( ) [[ ]]which follows from the premise of the lemma. □

Remark 2.19 The opposite implication does not hold in case = .

Denotation of constructors. If :: Δ : and is a function from type variables to sets, we define the set [[ ]]_{}by recursion on as follows.

Case

= \frac{:  Δ  +}{Δ :}

We define [[ ]]_{}= ( ).

Case

= \frac{: Σ}{Δ :}

In this case, we simply return the semantics of , which is defined elsewhere: [[ ]]_{}= Sem( ).

Case

= \frac{\begin{matrix}^{} \\ Δ :  : ^{} \end{matrix}}{Δ  :  ^{}}

The semantics of is a function over [[ ]], defined by [[ ]]_{}( [[ ]]) := [[ ^{}]]_{[ ]} . Note that this is only possible if we know the domain of the function ( , in this case). This is the reason why we define the semantics of derivations instead of constructors (where we would not have the domain available).

Case

= \frac{\begin{matrix}_{1} \\ Δ  :  ^{} \end{matrix}\begin{matrix}_{2} \\ ^{1} Δ : \end{matrix}}{Δ  : ^{}}

Let := [[ _{1}]]_{}and := [[ _{2}]]_{}. We simply define [[ ]]_{}:= [[ _{1}]]_{}([[ _{2}]]_{}). If is not a function or not in the domain of , then the application is defined to be the empty set.

Lemma 2.20 (Well-definedness and monotonicity) Let :: Δ : . If [[Δ]]then [[ ]]_{}[[ ]]_{^{}}[[ ]].

The lemma generalizes to -monotonicity:

Corollary 2.21 ( -monotonicity) Let :: ^{1} Δ  : . If  ^{}[[Δ]]then

[[ ]]_{}^{}[[ ]]_{^{}}[[ ]].

Proof. By case distinction on , using Lemma 2.18. □

Proof of the lemma. By induction on .

Case

= \frac{:  Δ  +}{Δ :}

Recall that [[ ]]_{}= ( ). Assuming ^{}[[Δ]], we implicitly require— since + —that ( ) ^{}( ) [[ ]]. Hence [[ ]]_{}[[ ]]_{^{}}[[ ]].

Case

= \frac{: Σ}{Δ :}

We require that Sem( ) [[ ]]for all ( : ) Σ.

Case

= \frac{\begin{matrix}^{} \\ Δ :  : ^{} \end{matrix}}{Δ  :  ^{}}

Recall that [[ ]]_{}( [[ ]]) = [[ ^{}]]_{[ ]} . Assuming ^{}^{}[[ ]], we have [ ] ^{}[ ^{}] [[Δ : ]]. By induction hypothesis, [[ ]]_{}( ) [[ ]]_{^{}}( ^{}) [[ ^{}]], which implies [[ ]]_{}[[ ]]_{^{}}[[ ^{}]].

Case

= \frac{\begin{matrix}_{1} \\ Δ  :  ^{} \end{matrix}\begin{matrix}_{2} \\ ^{1} Δ : \end{matrix}}{Δ  : ^{}}

Assume ^{}[[Δ]]. By induction hypothesis, [[ _{1}]]_{}[[ _{1}]]_{^{}} [[ ^{}]]. By second induction hypothesis, using the corollary, we have [[ _{2}]]_{}^{}[[ _{2}]]_{^{}}[[ ]]. Hence, the application [[ ]]_{}= [[ _{1}]]_{}([[ _{2}]]_{}) [[ ^{}]]is well-defined, and further, [[ ]]_{}[[ ]]_{^{}}[[ ^{}]]. □

The remainder of this section is devoted to the proof that two well-kinded-ness derivations for the same constructors do not yield different semantics. More precisely, assume two derivations :: Δ : and ^{}:: Δ^{}: and two valuations [[Δ]] and ^{}[[Δ^{}]]. If ( ) = ^{}( ) for all FV( ), then [[ ]]_{}= [[ ^{}]]_{^{}}. This result is not completely trivial, i. e., cannot be proven directly by induction on the derivations, since in derivations for non- -normal , some kinds in the middle of derivations can be canceled out. For example, consider = ( ) . Some kind for (and ) is mentioned in the middle of a well-kindness derivation of , but it can differ from derivation to derivation. Still, the semantics of in environment should be just ( ), independent of kind .

-normal forms are given by the grammar

::=

One step -reduction on constructorsbeta-red@ -reduction of constructors _{} is defined as usual. Since the simply-typed -calculus is strongly normalizing, it is clear that well-kinded constructors Δ : reach a normal form: _{}^{}for some .

Lemma 2.22 (Derivation-independence for normal forms) Assume two derivations ^{1} :: Δ^{1} : and ^{2} :: Δ^{2} : of well-kindedness for the same normal form , and two valuations ^{1} [[Δ^{1}]]and ^{2} [[Δ^{2}]]. If ^{1}( ) = ^{2}( ) for all FV( ), then [[ ^{1}]]_{^{1}} = [[ ^{2}]]_{^{2}}.

Proof. By induction on . This is easy, since both derivations are deterministic.

Case = . For = 1 2 the derivation ^{}has the shape

\frac{( : ) Δ^{}\begin{matrix}_{}^{} \\ _{}^{1} Δ^{}_{}: _{} \end{matrix}for = 1 }{Δ^{}:}

For all we have _{}:= [[ _{}^{1}]]_{^{1}} = [[ _{}^{2}]]_{^{2}} by induction hypothesis. Since
:= ^{1}( ) = ^{2}( ) by assumption, it follows that [[ ^{1}]]_{^{1}} = =
[[ ^{2}]]_{^{2}}.

Case = . Analogously.

Case = ^{}. For = 1 2 the derivation ^{}has the shape

\frac{\begin{matrix}^{} \\ Δ^{}: _{1}  ^{}: _{2} \end{matrix}}{Δ^{}^{}: _{1}  _{2}}

Let ^{}( ) := [[ ^{}]]_{^{}[ ]} . Since by induction hypothesis ^{1}( ) = ^{2}( )
for all [[ _{1}]], we have [[ ^{1}]]_{^{1}} = ^{1} = ^{2} = [[ ^{2}]]_{^{2}}. □

Lemma 2.23 (Substitution) Let _{1} :: Δ : : ^{}and _{2} :: ^{1} Δ : . Then there exists a derivation :: Δ [ ] : ^{}. Further, assume [[Δ]]and let ( ) := [[ _{1}]]_{[ ]} and := [[ _{2}]]_{}. Then [[ ]]_{}= ( ).

Proof. By induction on _{1}. □

Lemma 2.24 (Subject reduction) Let [[Δ]]. If :: Δ  : and  _{}^{}

then exists a derivation :: Δ ^{}: with [[ ]]_{}= [[ ]]_{}.

Proof. By induction on _{}^{}, using Lemma 2.23 in case of a -contraction.

□

Corollary 2.25 The lemma generalizes to multi-step reduction _{}^{}^{}.

Theorem 2.26 (Derivation-independence of semantics) Assume two derivations :: Δ : and ^{}:: Δ^{}: and two valuations [[Δ]]and ^{}[[Δ^{}]]. If ( ) = ^{}( ) for all FV( ), then [[ ]]_{}= [[ ^{}]]_{^{}}.

Proof. By normalization of -reduction _{}^{}. The theorem follows from Lemma 2.22 and the last corollary. □

This result justifies the notation [[ ]]_{}^{}as shorthand for [[ ]]_{}where :: Δ : for some Δ such that [[Δ]]. If is clear form the context of discourse, we will omit it.

Theorem 2.27 (Soundness of constructor equality and subtyping)

1. If :: Δ = ^{}: and ^{}^{}[[Δ]], then [[ ]]_{}^{}[[ ]]_{^{}}[[ ]].

2. If :: Δ  ^{}: and  ^{}[[Δ]], then [[ ]]_{}[[ ]]_{^{}}[[ ]].

Proof. Simultaneously by induction on . □

Type-Based Termination

In this chapter, we present the term or program level of F_{}. We introduce rules for typing and reduction and show their soundness through a term model. As a consequence, each program of F_{}is terminating, and even strongly normalizing.

3.1 Specification

In this section, we introduce the terms of F_{}with their typing and reduction rules.

3.1.1 The Language

Terms. The term language we use in this chapter is quite simple, it consists of the Curry-style -calculus with two special constants for recursion and corecursion.

Tm  ::=  -calculus
constant
Const  ::= fix_{}^{}funct. def. by recursion on + 1st argument
fix_{}^{}corecursive function with arguments

We use fix_{}^{}to denote either fix_{}^{}or fix_{}^{}. The default for subscript is 0, hence, fix^{}denotes recursion on the first argument, and fix^{}means the construction of an infinite object.

In spite of its economic spirit, the untyped -calculus can express all computable functions: it is Turing-complete. We heavily restrict its power through typing, but it is well-known that already in the simply-typed -calculus, many data structures can be simulated through continuation passing.

Example 3.1 (Pairs and Variants) Pairs with projections and variants (elements of a disjoint sum) with case distinction can be implemented as follows:

K  :=  constant function constructor
K^{}:=  identity function constructor
pair :=  constructor
fst := K first
snd :=  K^{}second projection
inl :=  left injection
inr :=  right injection
case :=

3.1.2 Typing

Typing contexts. We extend our notion of context: Now a context may not only assign kinds and polarities to type variables , but also types to term variables .

Γ ::=  empty context
Γ :  extension by constructor variable
Γ :  extension by term variable

The default polarity is non-variant; extension of a context by a non-variant type variable may be written Γ : instead of Γ : .

Typing contexts Γ will also be used in kinding judgements like Γ : , as defined in Section 2.1.4. In this case, the term variable declarations are irrelevant and should be considered absent.

Well-formed typing contexts Γ cxt. Contexts for typing must contain only non-variant type variable declarations; and each term variable must be declared with a well-formed type.

cxt-empty \overline{cxt}  cxt-tyvar \frac{Γ cxt}{Γ : cxt}

cxt-var \frac{Γ cxt  Γ  :}{Γ : cxt}

The restriction to non-variant type variables in rule cxt-tyvar will be understood when the typing rules are given below. The only typing rule which introduces type variables is generalization, ty-gen , and it only introduces nonvariant variables. However, allowing all polarities in the grammar for typing contexts Γ pays off when we pass from typing to kinding judgements Γ : , because those derivations introduce also co- and contravariant type variables (and they do not impose a well-formedness criterion).

Lemma 3.2 If :: Γ cxt and ( : ) Γ then Γ : .

Proof. By induction on . □

Notation. Addition + of a size expression : ord and a natural number ℕ.

\begin{aligned}+ 0 & = & \\ + ( + 1) & = & s + \end{aligned}

Typing Γ : .

Lambda-calculus. These rules are standard:

ty-var \frac{( : ) Γ  Γ cxt}{Γ  :}  ty-abs \frac{Γ :  :}{Γ  :}

ty-app \frac{Γ  :  Γ  :}{Γ  :}

Quantification. Since _{}: ( ^{}) ^{+} (see Section 2.1.3), the constructor is of kind ^{}in the following rules:

ty-gen \frac{Γ :  :}{Γ  : _{}}FV( )  ty-inst \frac{Γ  : _{}Γ  :}{Γ  :}

For rule ty-inst note that since Γ : ^{}, the application is only well-kinded in Γ if the context for : mentions only non-variant variables (see kinding rule kind-app in Section 2.1.4). But this is the case, since Γ is well-formed (see Lemma 3.4).

Subsumption. (Subtyping has been defined in Section 2.2.)

ty-sub \frac{Γ  :  Γ  :}{Γ  :}

Folding and unfolding for (co)inductive types ( ).

ty-fold \frac{Γ  : ( _{}) }{Γ  : _{}( + 1) }  ty-unfold \frac{Γ  : _{}( + 1) }{Γ  : ( _{}) }

Recursion ( = ) and corecursion ( = ).

ty-rec \frac{Γ fix_{}^{}-adm Γ  : ord  Γ cxt}{Γ fix_{}^{}: ( :ord  ( + 1))}

The condition fix_{}^{}-adm ensures that we only use ty-rec to define recursive ( = ) or corecursive ( = ) functions. Dropping the condition we could immediately introduce non-terminating programs, e. g., for ( ) = Nat^{}Nat^{}which does not depend on the size index, the diverging program fix_{0}^{}succ ( ) would be accepted.

For fix_{}^{}-adm we say that is admissible for recursion on the + 1st argument. Similarly, fix_{}^{}-adm is pronounced is admissible for corecursion with arguments. A definition of these predicates is given below.

Example 3.3 (Typing for Pairs and Variants) The following type assignments show that the constructors and destructors given in Example 3.1 introduce and eliminate Cartesian product and disjoint sum type as presented in Example 2.5 (impredicative encodings).

pair :
fst :
snd :
inl :  +
inr :  +
case :  + ( ) ( )

Lemma 3.4 If :: Γ : then Γ cxt.

Proof. By induction on . At the leaves (ty-var and ty-rec ) of the typing derivation, Γ cxt is checked, and no rule, read downwards, extends the context.

□

Lemma 3.5 If :: Γ  : then Γ  : .

Proof. By induction on . In most rules the type of the conclusion is simply assembled from components of the type(s) of the premise(s). In rule ty-sub ,

the premise Γ  : entails Γ  : (by Lemma 2.14).  □

Notation for size index. We sometimes write the size index superscript, e. g., instead of , or ^{}instead of .

Natural transformations. Let 0. For constructors _{1}, … _{}and with : , let

:  : _{1} _{}

Also, we abbreviate ( _{1} ) ( _{}) by .

Admissible types for recursion and corecursion must meet certain requirements. For completeness of the typing system, we give the judgements Γ fix_{}^{}-adm for here. We will motivate and repeat them in sections 3.5.1 and 3.5.2.

Γ fix_{}^{}-adm :  Γ :ord  = ( ( ^{}) ) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ :+ ord : ^{}for some ^{}= ^{} Γ : ord _{}: ^{}for 1 and Γ _{}: ^{}_{}for 1

Γ fix_{}^{}-adm :  Γ :ord  = ( ( ^{}) ) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ : ord _{}: ^{}(all ) for some ^{}= ^{}and Γ _{}: ^{}_{}for 1

Example 3.6 (Admissible types for recursive functions) These ( ) are fix_{}^{}-adm for some .

Nat^{}Nat^{}Nat^{}addition and multiplication
Nat^{}Nat^{}Nat^{}subtraction and division
List^{}List^{}list map
List^{}List^{}List^{}list splitting

The following types types are not admissible according to the current criterion, but will be admissible after a relaxation in Chapter 5.

Nat^{}Nat^{}Nat^{}minimum and maximum
List^{}List^{}List^{}list zip-with

Example 3.7 (Repeat function) The term repeat constructs an infinite stream of s.

repeat := fix_{0}^{}repeat pair repeat
repeat :  Stream^{}

It is well-typed, since repeat pair repeatcan be assigned type Stream^{} Stream^{+1} , and Stream^{}is trivially fix_{0}^{}-adm (empty , ).

3.1.3 Operational Semantics

In the following, we give the operational semantics of F_{}. It is clear that, in order to obtain a strongly normalizing calculus, the unrolling of recursion has to be restricted. It is safe to unroll a recursive function if all of its arguments are values, however, it is sufficient if the recursive argument is a value (i. e., the argument which decreases in the recursive call). In F_{}, the number of the recursive argument is associated with the index of the recursion operator. A candidate for the unrolling rule is

fix_{}^{}_{1}( ) (fix_{}^{}) _{1}( )

since a -abstraction is the canonical value in F_{}. Considering this for another moment, we see that recursive and corecursive functions must also count as values, since they are not eagerly unrolled, and under-applied constants, such as a bare fix_{}^{}, should also be included. Anyhow, when we extend F_{}with more primitive type constructors, more values will arise. So we trade the rule for the following:

fix_{}^{}_{1} (fix_{}^{}) _{1}

What about corecursion? A corecursive function should also only be unrolled on demand. Could we use the same rule for fix_{}^{}—which would make the distinction between fix^{}and fix^{}superfluous? Actually, the above rule is too strict for corecursion, it prevents sensible reductions. Consider, the type of Burroni conatural numbers^{1} and their mapping function:

Bur : ord ^{+} ^{+}
Bur :=  ^{}+
=  ^{}( ) ( )
bmap :  ( )  Bur^{}Bur^{}
bmap :=  fix_{1}^{}bmap case ( inl ( )) ( inr (bmap ))
=  fix_{1}^{}bmap (  ( )) (  (bmap ))

Now we expect case (bmap (inl )) to reduce to ( ) even for variables , , and . Expanding case and inl this simplifies to

(fix_{1}^{}( bmap ) ( ^{}^{}^{}))

Since variable is not a value, this term would be stuck with the evaluation rule for fix^{}. Unrolling on demand means for corecursive elements: unrolling in any evaluation context. This can be application to a variable like , or being applied to a recursive function.

It is also clear that a corecursive function cannot be unrolled before all of its arguments have been supplied and the result is demanded. For instance, we cannot allow a reduction rule like

(fix_{}^{}_{1})  ( (fix_{}^{}) _{1})  where

1Capretta [Cap05] interprets Bur^{}as computations of type : Either it is a value of type (inl) or it is a “step” containing a computation of type (inr). “Step” could be read as “hello, I know you are waiting for the result, I just want to tell you that I am still alive and busy with the computation”. A diverging computation is an infinite sequence of steps (fix_{0}^{}inr).

This rule leads to divergence of well-typed terms if . For example, consider the coinductive type of Bool-hungry functions ^{}Bool and the function (communicated to me by Tarmo Uustalu during the APPSEM meeting in Nottingham 2003)

veryHungry :  Bool ^{}Bool
veryHungry := fix_{1}^{}veryHungry ^{}veryHungrytrue

Then veryHungry true would reduce in several steps to ^{}veryHungry true and, hence, diverge. But the above reduction rule is sound for = . This we will show in the remainder of the chapter.

Evaluation frames and contexts.

Eframe  ::= _application
fix_{}^{}_{1}_recursive function call
Ecxt  ::= Id  empty stack
push frame

Frames and contexts can be interpreted as endo-functions on terms in the obvious way, i.e.,

\begin{aligned}(_)( ) & := & \\ (fix_{}^{}_)( ) & := & fix_{}^{} \\ Id( ) & := & \\ ( )( ) & := & ( ( )) \end{aligned}

Hence, by abuse of notation, Eframe Ecxt Tm Tm.

The head of a term is the shortest term such that ( ) = for some evaluation context . For example if = fix_{}^{}_{1}(( ^{}) ^{}), then ^{}is the head of .

(Lazy) Values. While a normal form is a term which cannot be reduced further, we will refer to a canonical form as a value.

Val  ::=
fix_{}^{}
fix_{}^{}where 0

Reduction. The contraction relation ↣ ^{}is given by the following axiom schemata:

red-  ( )  ↣ [ ]
red-rec  fix_{}^{}_{1} ↣ (fix_{}^{}) _{1}  if = fix_{^{}}^{}^{}_{1 ^{}}
red-corec  (fix_{}^{}_{1}) ↣ ( (fix_{}^{}) _{1}) if = fix_{^{}}^{}^{}_{1 ^{}}_

Furthermore, we define the one-step reduction relation as closure of ↣ under all term constructors, ^{+} as the transitive closure of and ^{}as the reflexive-transitive closure.

Remark 3.8 (On the choice of red-rec ) Why have we restricted the unfolding of recursive functions to call-by-value? First, note that the completely unrestricted unrolling of fixed points, fix_{}^{}(fix_{}^{}), gives immediately rise to infinite reduction sequences. Secondly, we need recursive functions to be evaluation contexts, i. e., a recursive function applied to a variable may not unfold the function definition. Otherwise, each function definition which contains a recursive call will immediately loop under full reduction.

Remark 3.9 (Confluence) If we omit the side conditions in the fixed-point unrolling rules red-rec and red-corec , then reduction would not be confluent, not even locally confluent for closed terms. Critical pairs would arise when in red-rec , the value was a corecursive function, or in red-corec , the evaluation frame was a recursive function; in this case, both rules could fire. For instance, let = _, = fix_{0}^{}, and = fix_{0}^{}. On one hand, , whose only reducts are ( ) and . On the other hand, ( ) which reduces further only to , , ( ) and . The deeper reason for non-confluence is that we cannot unfold all fixed-points, since we want to ensure normalization.

In order to overcome this defect, we have inserted restrictions that remove the critical pairs, make reduction confluent and weak head reduction deterministic.

Remark 3.10 (Why prevent both reductions?) For a term with clashing fixed points, e. g., := fix_{0}^{}(fix_{0}^{}^{}), we currently allow no contraction. As we have seen in the previous remark, allowing both fixed-point reductions would lead to non-confluence, and it would even break a crucial property of strongly normalizing terms: they are closed under weak head expansion^{2} (see Remark 3.27). But could we not give priority to one kind of fixed-points and keep one reduction of the two? This would break symmetry, but does it do any harm? Yes, as we will see in the proofs of lemmata 3.32 and 3.37. The term would not be considered neutral; removing the reduction of fix^{}would break the first lemma (3.32), and removing the reduction of fix^{}would break the second one (3.37).

For system F_{}, we are only interested in strong normalization. We will present a better behaved, iso-(co)inductive, system in Section 4.1 and show that its normalization can be inherited from F_{}.

Example 3.11 (Reduction for repeat) Let be a type and : . Recall that repeat = fix_{0}^{}( repeat pair repeat). We have the following reduction sequences

2Here, we mean a restricted form of weak head expansion, which usually preserves strong normalization. E.g., [ ] only expands to ( ) if is strongly normalizing.

fst (repeat )  (repeat ) K
( repeat pair repeat) (repeat ) K
pair (repeat ) K
3 K (repeat )
2
snd (repeat )  ^{+} K^{}(repeat )
repeat

Note that repeat does neither reduce by itself, nor as argument to a nonrecursive function like pair, K, etc. (lines 2–4). It only reduces if it is applied to something (line 1). This fixed-point unfolding on demand is a generalization of the strategy of Amadio and Coupet-Grimal [ACG98], Giménez [Gim98], and Barthe et al. [BFG^{+} 04], who unfold corecursive definition only under case distinction.

Although there are variations on the order of reductions, one will find that there is no possibility that the fixed-point repeat is unfolded more than once. Each unfolding “eats” one destructor (like fst or snd), which guarantees termination.

Lemma 3.12 (Substitution) Reduction is closed under substitution.

1. If  ^{}then [ ]  [ ] ^{}.

2. If ^{}then [ ] ^{}[ ^{}] .

Proof. The first by induction on  ^{}, the second by induction on .  □

Example 3.13 (Types not admissible for recursion) There are types which are OK in the domain-theoretic semantics of Hughes, Pareto, and Sabry [HPS96], but not in our current reduction semantics:

Nat^{}Nat^{}Nat^{}addition and multiplication (uncurried)
List^{}List^{}List^{}list zip-with (uncurried)

We discuss modification of our semantics in Section 7.2.

But these types are not admissible and lead to undefined recursive functions.

List^{}(Nat^{})  admits function fix_{0}^{}_nil
Nat^{}(Nat Nat^{})  see Section 5.1
(Nat Nat^{})  ditto

3.2 Examples

To flesh out the definition of F_{}, we present some simple examples in this section. More examples will be given in Chapter 6. If clear from the context, we will write Nat for Nat^{}to denote the type of all natural numbers.

3.2.1 Fibonacci Numbers

A basic exercise in lazy functional programming is to code up the stream of Fibonacci numbers in one line, assuming we have the standard library function

zipWith :  (  )

Stream^{}Stream^{}Stream^{}

zipWith :=  fix_{2}^{}zip  pair ( (fst ) (fst )) (zip(snd ) (snd ))

Note that the type of zipWith is admissible for corecursion, since appears negatively in Stream^{}and Stream^{}. In F_{}, the Fibonacci stream can be defined as follows (assuming 0 1 : Nat and + : Nat Nat Nat).

fib : Stream^{}Nat
fib := pair 0 (fix_{0}^{}zip pair 1 (zipWith (+) zip (pair 0 zip)))

The body of the corecursive definition is well-typed. We assign the following types:

zip  : Stream^{}Nat
pair 0 zip  : Stream^{+1} Nat Stream^{}Nat
(zipWith )  : Stream^{}Nat
pair 1 (zipWith ) : Stream^{+1} Nat

It is instructive to understand why the alternative definition of the Fibonacci stream as

fix_{0}^{}fib pair 0 (pair 1 (zipWith (+) (snd fib) fib)

is not well-typed in F_{}.

3.2.2 Co-Natural Numbers

Non-standard natural numbers are given by the type CoNat = ^{}1 + . We can define all natural numbers plus infinity:

\overline{0} := inl()
\overline{1} := inr \overline{0}
\overline{2} := inr \overline{1}
⋮
\overline{}:= fix_{0}^{}inr

All these values inhabit CoNat.

3.2.3 Some Pathological Cases

Datatypes like Empty^{}:= _{}^{}are called unguarded since their unfolding does not produce a “real” data type constructor like +, , or , which would enable production of inhabitants. Since [[Empty]]( + 1) = [[Empty]]( ), we have [[Empty]] = ^{}. It is easy to check that fix_{0}^{}: Empty^{}, so the Empty type can be eliminated through a recursive function. A bit counterintuitively, this function, which is the primary example of a looping definition in functional programming, is termination on all inputs—simply because we can never construct a value of Empty^{}.

Dually, the unguarded coinductive type Unit^{}:= _{}^{}is inhabited by fix_{0}^{}. This function is normalizing as well because there is no well-typed evaluation context for elements of type Unit^{}.

3.2.4 Huffman Trees

Huffman codes are space-optimal and prefix-free. To decode a Huffman-coded bit stream, one uses a Huffman tree, i. e., a binary tree whose leaves are labeled by the characters whose code is the path to their leaf. In Haskell, we can implement the decoding function as follows.^{3}

data Huffman b c = Leaf c
                 | Node (b -> Huffman b c)
decode :: Huffman b c -> [b] -> [c]
decode t0 = dec0
    where dec0 = dec1 t0
              where dec1 (Leaf c) bs     = c : dec0 bs
                    dec1 (Node f) (b:bs) = dec1 (f b) bs

There are two subroutines: the corecursive dec0 of type [b] -> [c] decodes a stream starting with the full Huffman-tree t0, whereas dec1, of the same type as decode, is defined by recursion on subtrees of t0. Observe that the recursive call to dec0 is guarded by the stream constructor (:), although not according to Coquand’s conditions [Coq93], because it is inside another fixed point.

In F_{}, we can define the type Huffman^{}of -branching -leaf labeled trees of height as follows:

Huffman : ord ^{+} ^{}^{+}
Huffman :=  _{}^{}+ ( )
leaf  :  Huffman^{+1}
leaf  := inl
node  :  ( Huffman^{}) Huffman^{+1}
node  := inr

3Yong Luo observed that decode (Leaf c) [] produces an infinite stream of cs. This shows that decode is not necessarily terminating on finite input, although it is, as we will prove in the following, productive. One could ask whether decode’s behavior on the singleton Huffman tree Leaf c makes sense. I think “yes”, because an infinite text over an alphabet with a single character contains no information. Regardless what the input stream of Huffman codes is, the output will just consist of cs. In this case, we do not even have to look at the input.

The decoding function takes a Huffman-tree and a -stream . If the is a node inr , we take the first element from the stream and continue with the -th subtree of , i. e., , and the remaining stream. If is a leaf inl , we can output and continue with the original Huffman tree _{0}.

decode :  Huffman^{}Stream^{}Stream^{}
decode :=  _{0} fix_{1}^{}dec_{0} fix_{0}^{}dec_{1}  case ( pair (dec_{0} )) ( dec_{1} ( (fst )) (snd )) _{0}

This code is a close translation of the Haskell program, one clearly sees the outer corecursion (fix_{1}^{}dec_{0}) and the inner recursion (fix_{0}^{}dec_{1}). We can assign the following types to variables and subterms:

0  : Huffman^{}
dec_{0}  : Stream^{}Stream^{}
dec_{1}  : Huffman^{}Stream^{}Stream^{+1}
: Huffman^{+1}
: Stream^{}
:
pair (dec_{0} )  : Stream^{+1}
:  Huffman^{}
(fst )  : Huffman^{}
dec_{1} ( (fst )) (snd ) : Stream^{+1}
fix_{0}^{}: Huffman^{}Stream^{}Stream^{+1}

The type of dec_{0} is admissible for corecursion with one argument, fix_{1}^{}-adm, since it is a function type into a coinductive type ^{}, and the domain is monotone in the size variable , since it does not mention it. Similarly, the type of dec_{1} is admissible for recursion on the first argument, fix_{0}^{}-adm, since its domain is an inductive type and its codomain is trivially monotone in the size variable .

This example could be handled in the calculus of Barthe et al. [BFG^{+} 04] and in my TLCA system [Abe03], but not in the system of Hughes, Pareto, and Sabry [HPS96, Par00], since they forbid function spaces in data types.

In the following, we allow ourselves some syntactic sugar and write the case-expression as pattern matching:

match with

leaf  pair
node  dec_{1}

Creating a Huffman tree. Huffman [Huf52] presented an algorithm how to create a optimal prefix-free binary code for a set of characters from their relative frequencies. This algorithm can be coded directly in F_{}. For simplicity, assume that the characters and their frequencies are given as a list of pairs ( _{1} leaf _{1}) ( _{}leaf _{}) of natural numbers and singleton Huffman trees. Assume further, this list is sorted ascendingly by frequencies (if not, sort it first—sorting can also be coded in F_{}, as we will see later).

We abbreviate the type of frequency-tree pairs by WT. Two pairs can be joined by adding the frequencies and constructing a node with the two given trees as subtrees:

WT :
WT := Nat Huffman^{}Bool Char
join : WT WT WT
join :=  pair (fst + fst ) ( snd (if then else ))

Huffman’s algorithm works as follows: Pick the pairs with the least frequencies, join them and solve the remaining problem. If we start with a sorted list, we have to insert the joined pair into the remaining list in order, before we recursively process the remainder. It is crucial that insert is defined in such a way that our type system can “see” that the extended list is only one element larger. But this is the case for the obvious recursive definition of insert, as for example present in the Haskell prelude. Here, we give a version slightly optimized for our purposes: it returns head and tail of the result list separately, in order to statically exclude the impossible case that an empty list is returned. (In the following, we consider frequency comparison for WT to be already defined.)

insert  :  WT List^{}WT WT List^{}WT
insert  := fix_{1}^{}insert xs match xs with
inl _pair xs
inr (pair ys) if then pair xs

else pair (inr (insert ys))

huffman :  WT List^{}WT Huffman^{}Bool Char
huffman := fix_{1}^{}huffman xs match xs with
nil  snd
cons ys  uncurry huffman(insert (join ) ys)

Herein, uncurry is an auxiliary function defined as usual.

uncurry :  (  )
uncurry :=  (fst ) (snd )
Using the impredicative encoding  = (  ) of prod-

ucts, we can state the last case without uncurry directly as

insert (join ) ys huffman It is easy to see that the recursive call to huffmanis justified. Some types are:

xs  : List^{}WT List^{+1} WT
ys  : List^{}WT
insert (join ) ys : WT List^{}WT
uncurry huffman : WT List^{}WT Huffman^{}Bool Char

Finally, Huffman encoding can also be coded in F_{}, although for this, we need another data structure, mapping characters to Huffman codes.

3.2.5 Prime Numbers

Productivity of certain streams depends on non-trivial mathematical results. For example, the stream of prime numbers is productive since there are infinitely many primes. If the converse was true, i. e., if there were only primes and the product of these primes, then + 1 would be relatively prime to all primes. This proof by Euclid guarantees a prime number between + 1 and + 1. We can exploit this fact to define a stream of prime numbers in F_{}. The definition is an adaption of Miculan and Gianantonio’s function ( ) [GM03, tenth page]:

( ) = :: (  + 1)  if gcd( ) = 1 ( + 1)  else

If F_{}, we require a dummy argument to count down the maximum number of steps until the next prime is found.

pr  :  Nat  Nat Nat^{}Stream^{}Nat
pr  := fix_{3}^{}pr
fix_{1}^{}pr^{}match with
zero
succ ^{}if gcd = 1 then

pair (pr( ) ( + 1) (( 1) + 1)) else pr^{}( + 1) ^{}

primes : Stream^{}Nat
primes := pr 1 2 1

Herein, gcd : Nat Nat Nat computes the greatest common divisor and + and denote sum and product of natural numbers. Since in each executed function instance pr the invariant + 2 = + holds, the case = 0 is impossible; otherwise the counter would have stepped over + 1 without finding a prime. Hence, the dots “… ” in the first match-branch will never be reached and can be replace with any term of the right type.

3.2.6 Sorting by Merging

The sorting algorithm whose termination is most easy to establish is insertion sort: insertion is primitive recursive, and sorting is performed by iteratively inserting elements into a list which is empty in the beginning. Quick sort is more difficult, since the recursive calls happen on indirect sublists. It has been treated elsewhere [Abe04]. This time, we treat merge sort. Let be some type with a total order : Bool. Sorted merging can be defined by lexicographic recursion on the two input lists.

merge :  List^{}List^{}List^{}
merge : fix_{0}^{}merge_{0} _{1} match _{1} with
nil  _{2} _{2}
cons xs  fix_{0}^{}merge_{1} _{2} match _{2} with
nil  _{1}

cons ys if then cons (merge_{0}xs _{2}) else cons (merge_{1}ys)

A more precise type for merge would be List^{}List^{+1} List^{+} (since the index counts the number of constructors as opposed to the length of the list, the +1 in the type of the second list is necessary—one nil constructor is discarded during the merge). But our type system, unlike Hughes, Pareto, and Sabry’s [HPS96], does not handle addition of sizes. ^{4}

Merge sort recursively splits the input list, until only singleton lists remain, and then merges the lists together in a sorted fashion. For our type system to accept merge sort, it is crucial to know that both output lists of the split operation are not longer than the input list (in most, but not all cases, they will be strictly shorter, namely half the length). The natural type for split is List^{}List^{}; with the impredicative encoding of products split can be written tail-recursive, in continuation-passing style (CPS).

split :  List^{}(List^{}List^{})
split := fix_{0}^{}split  match with
nil  nil nil
cons xs  splitxs( ys zs (cons zs) ys)

We assign the following types.

split  : List^{}(List^{}List^{})
: List^{+1}
: (List^{+1} List^{+1} )
:
xs  : List^{}
splitxs  : (List^{}List^{})
ys zs  : List^{}
cons zs ys : List^{+1}
(cons zs) ys :

4Although there is an addition on ordinals, it is not commutative and hence would be a bit misleading in a type system (since most programmers would think of natural number addition).

We could, however, introduce another kind nat of finite sizes which supports addition.

The type of splitis fix_{0}^{}-adm since the result type (List^{}List^{}) is positive in size variable .

Finally, we define merge sort msort via an auxiliary function msort^{}such that msort^{}assorts the list cons asby merging.

msort : List^{}List^{}
msort :=  match with
nil  nil
cons as  msort^{}as
msort^{}:  List^{}List^{}
msort^{}:= fix_{1}^{}msort xs match xs with
nil  cons nil
cons  split ( as bs merge (msort as) (msort bs))

The recursive calls to msortare legal because of the typing of split. Indeed, we can assign the following types:

msort :  List^{}List^{}
:
xs  : List^{+1}
: List^{}
as bs : List^{}

Altenkirch, McBride, and McKinna [AMM05] demonstrate that sorting by merging can be implemented in a structurally recursive fashion by explicating the computation pattern into an inductive data type. Applying short-cut fusion^{5} to their program, one arrives at the usual functional formulation of merge sort. They point out that Turner [Tur95] has also defused quick sort, arriving at the structural tree sort [Bur69].

3.2.7 A Heterogeneous Data Type of Lambda Terms

In Haskell, we can define heterogeneous, also called nested, data types, for instance:

data TLam a = Var a
            | App (TLam a) (TLam a)
            | Abs Ty (TLam (Maybe a))

(Herein, Ty denotes some Haskell type of object-level type expressions.) The type TLam a is called heterogeneous, since the argument to the data type constructor TLam varies in a recursive occurrence on the right hand side. It is inhabited by de Bruijn representations of typed lambda terms over a set of free variables “a”. A similar type has been studied by Altenkirch and Reus [AR99] and Bird and Paterson [BP99b]; a precursor has been considered already by Pfenning and Lee [PL89] and Pierce, Dietzen, and Michaylov [PDM89]. The constructor for lambda-abstraction Abs expects the type of the abstracted variable and a term over the extended set of free variables Maybe a, which is the Haskell representation of the sum type 1 + a. The disjoint sum reflects the choice for a bound variable under the abstraction: either it is the variable freshly bound (left injection into the unit set “1”) or it is one of the variables that have been available already (right injection into “a”).

5Intermediate tree structures are eliminated by the acid rain theorem.

In F_{}, we can express the type constructor TLam by a least fixed point of

kind ^{+} .

Ty  :
TLam : ord ^{+} ^{+}
TLam :=  ^{}_{^{+}}  + (  + Ty (1 + ))
var  :  TLam^{+1}
var  :=  inl
app :  TLam^{}TLam^{}TLam^{+1}
app :=  inr (inl  )
abs  :  Ty^{}TLam^{}(1 + ) TLam^{+1}
abs  :=  inr (inr  )

A whole article [AMU05] has been devoted to functions defined by iteration over heterogeneous data types. F_{}can simulate all the systems discussed in that article, hence, all examples in that article can be replayed in F_{}. In F_{}, some functions can be given more precise typings, e. g., the functoriality/monotonicity witness of TLam:

map_{TLam} :  ( ) TLam^{}TLam^{}
map_{TLam} := fix_{1}^{}map_{TLam}  match with
var  var ( )
app  app (map_{TLam} ) (map_{TLam} )
abs  abs (map_{TLam} (lift ) )
lift  :  ( ) (1 + 1 + )
lift  :=  match with
inl  inl
inr  inr ( )

The call map_{TLam} renames all free variables in according to ; the structure of remains unchanged, which is partially reflected in the type of map_{TLam}: it expresses that the output term is not higher than the input term. The type of recursion is polymorphic:

( ) = ( ) TLam^{}TLam^{}

This is typical for functions over heterogeneous data types; in our example, since in the recursive call map_{TLam} (lift ) the argument has type TLam^{}(1+ ), the variable of the recursion type ( ) has to be instantiated to 1 + . It is well-known that type reconstruction for polymorphic recursion is undecidable [Hen93, KTU93], hence, we cannot hope for an autonomous type inference algorithm for F_{}.

This example will be continued in Section 6.3.

3.2.8 Substitution for Finite and Infinite Lambda-Terms

Altenkirch and Reus [AR99] describe a substitution function for de Bruijn-style lambda-terms as a heterogeneous data type. During substitution under a abstraction, a new free variable is temporarily introduced, hence, all free variables in the substitute terms have to be lifted (renamed). Altenkirch and Reus perform this lifting operation also using substitution, and give a lexicographic termination argument. McBride [McB06] has, besides generalizing it to typed lambda-terms, exhibited the primitive recursive structure behind this algorithm, by giving a single traversal function for lambda-terms that is then instantiated to yield renaming or substitution. In the following, we demonstrate that we can replay his development in F_{}, although only for untyped terms, and that the same algorithm is recognized to be productive for infinite lambdaterms.

The generating type constructor for untyped de Bruijn terms is LamF, from which we get the types of finite (Lam) and infinite (CoLam) terms:

LamF : ( ^{+} ) ^{+} ^{+}
LamF :=  + (  + (1 + ))
Lam  : ord ^{+} ^{+}
Lam  :=  ^{}_{^{+}}LamF
CoLam : ord ^{}^{+}
CoLam :=  ^{}_{^{+}}LamF

The data constructors are uniformly definable for finite ( = ) and infinite ( = ) terms:

var :  ^{+1} LamF
var :=  inl
app :  ^{}LamF  ^{}LamF  ^{+1} LamF
app :=  inr (inl  )
abs :  ^{}LamF (1 + ) ^{+1} LamF
abs :=  inr (inr )

In the absence of sized types, renaming and substitution can be subsumed under the common type

(  ) LamF  LamF

where is instantiated with the identity in case of renaming, and with Lam in case of substitution. We are dealing with sized types, however, and in the case of infinite terms we would like that both renaming and substitution are of type CoLam^{}CoLam^{}. This means that the result of renaming and substitution is defined at least up to the same depth than the input. Hence, we let depend on a size argument and obtain the type

( ^{}) CoLam^{}CoLam^{}

McBride parameterizes the generic traversal function for de Bruijn terms by a kit that is passed as an extra argument to the traversal function. The kit contains three functions: a mapping from variables into , a mapping from to terms, and a lifting function on . For our purposes is more convenient to separate the second function from the rest. We say has term structure if it is pointed and supports lifting:

TmStr : (ord ^{}^{+} ) ^{}
TmStr :=
( ^{+1} ) ( ^{}^{}(1 + ))

We have chosen to be antitonic in the size index since we will later instantiate it with CoLam.

If has term structure, we can lift functions : ^{+1} to make room for one extra variable:

lift :  :ord ^{}^{+} TmStr
(  ^{+1} ) (1 +  ^{+1} (1 + ))
lift :=  vr wk ma match mawith
inl  vr(inl )
inr  wk( )

Generic traversal now works for all which can be converted to terms using the parameter tm. It is defined as follows:

trav :  :ord ^{}^{+} TmStr (  ^{+1}  ^{+1} LamF )
(  ^{}) ( ^{}LamF  ^{}LamF )
trav :  tm fix^{}trav  match with
var  tm( )
abs  abs (trav(lift ) )
app  app (trav ) (trav )

Note that : ^{+1} , but, in the recursive call, trav expects to be of type ^{}. This is fine because is antitone in its size argument, hence +1 ^{}. In case of = , fix^{}has to be instantiated with fix_{1}^{}, and with fix_{2}^{}in case of = . In both cases, the type

( ) =  (  ^{}) ( ^{}LamF  ^{}LamF )

is admissible for (co)recursion, again since is antitonic.

Instantiating with , we obtain the renaming function for free variables:

rename :  ( ) ^{}LamF  ^{}LamF
rename := trav id inr var

Substitution for infinite terms is obtained by the instantiation = CoLam:

subst :  ( CoLam^{}) CoLam^{}CoLam^{}
subst := trav var rename inr id

The best type we can give to substitution of finite terms in F_{}is ( Lam^{}) Lam^{}Lam^{}. We first have to type-check trav with a specialized type, and then instantiate it with = Lam^{}:

trav :  : ^{+} TmStr ( ) (  Lam^{})

( ) (Lam^{}Lam^{})

subst :  ( Lam^{}) Lam^{}Lam^{}
subst := trav var rename inr id

3.3 Limits, Iteration, and Fixed-Points

In this section, we will define transfinite iteration to give a semantics to inductive and coinductive types. We will calculate the closure ordinal ^{ord} of iteration, such that, and are indeed fixed-points. This will justify the rules ty-fold and ty-unfold for the case = .

3.3.1 Limits

Let (O ) be some complete linear ordering, e.g., the set of ordinals up to ^{ord} and (𝔏 inf sup) some complete lattice. For O 𝔏 and 0 a limit ordinal in O we define:

inf_{}:= inf_{}( )  infimum
sup_{}:= sup_{}( )  supremum
lim inf _{}:= sup_{_{0}} inf_{_{0}} ( )  limes inferior
lim sup _{}:= inf_{_{0}} sup_{_{0}} ( )  limes superior

Lemma 3.14 (Relationships) In the above context, if = 0,

inf_{}lim inf_{}lim sup_{}sup_{}

If lim inf _{}= lim sup _{}= for some 𝔏, we say that the limit of at exists and set lim_{}= .

Lemma 3.15 (Limes inferior of monotone function) If is monotone below , i. e., ( ) ( ) for all , then lim inf _{}= sup_{}.

Proof. For monotone it holds that inf_{_{0}} ( ) = ( _{0}). □

Corollary 3.16 If is monotone below , then lim_{}= sup_{}.

Lemma 3.17 (Limes superior of antitone function) If is antitone below , then lim sup _{}= inf_{}.

Proof. For antitone it holds that sup_{_{0}} ( ) = ( _{0}). □

Corollary 3.18 If is antitone below , then lim_{}= inf_{}.

A function is continuous in , if ( ) = lim_{}. Here we mean continuous in the sense of classical analysis, not in the sense of domain theory, where continuity includes monotonicity.

3.3.2 Operator Iteration

By the theorem of Knaster and Tarski we know that in each complete lattice 𝔏 least and greatest fixed-points of monotone operators 𝔏 𝔏 exist. The least fixed-point of , for instance, can be defined either “from above” as inf ( ) or from below as the th iterate ^{}( ) for some sufficiently large ordinal . We choose the second alternative since our system F_{} also speaks about approximations ^{}( ) for . In the following we will make it clear what we mean by transfinite iteration ^{}( ) in arbitrary complete lattices 𝔏—we will of course only use the notion for our operator lattices [[ ]], but the specifics about the lattice do not matter for iteration and fixedpoints.

Transfinite iteration. Let  𝔏 𝔏 be an endo-function,  𝔏 and an

ordinal number. We define the -iterate I_{}of at by transfinite recursion on .

I_{0}  :=
I_{+1}  := (I_{})
I_{}:= lim inf _{}(I_{})

We use ^{}( ) as a shorthand for I_{}. For the limit case, we chose to use the limes superior, as Danner [Dan99]. Note that iteration is well-defined for any , in particular, non-monotonic . However, many reasonable properties on iteration hold only for a monotonic .

Lemma 3.19 (Iteration of monotonic function) If ^{}𝔏 ^{+} 𝔏 then I_{} I_{}^{}𝔏 ^{+} 𝔏 for any On.

Proof. By induction on . □

For iteration to be monotonic in the ordinal index, we need to start iteration at an element 𝔏 for which is inflationary, meaning ( ) . When we use iteration to define the semantics of , iteration will start at = , for which any is trivially inflationary, hence the semantics of will be monotone in the ordinal argument for any monotone .

Lemma 3.20 (Iteration of inflationary function^{6}) Let  𝔏 ^{+} 𝔏 and  𝔏

with ( ). Then

1. ^{}( ) ^{}( ) for , and

2. ^{}( ) ^{+1} ( ).

Proof. Simultaneously by induction on . Since is reflexive, it is sufficient to show ^{}( ) ^{}( ) for instead of proposition 1.

Case = 0. For part 1, there is nothing to show, part 2 follows by assumption.

Case = ^{}+ 1. For part 1, assume ^{}+ 1. By induction hypothesis 1, ( ) ^{^{}}( ), and by induction hypothesis 2, ^{^{}}( ) ^{^{}+1} ( ). Hence the claim follows by transitivity. For part 2, just use monotonicity of on the induction hypothesis.

Case = limit ordinal. For part 1, assume . Since by induction hypothesis 1 function ^{}( ) is monotone below , by Lemma 3.15 it is sufficient to show that ^{}( ) sup_{}^{}( )—which trivially holds. For part 2 we can apply Lemma 3.15 similarly which leaves us the goal sup_{}^{}( ) ^{+1} ( ). Assume an arbitrary . By induction hypothesis 1, ^{}( ) ^{}( ), hence by monotonicity ^{+1} ( ) +1 ( ). Since was arbitrary and ^{0}( ) ^{1}( ) by assumption, it

holds for all  that ^{}( ) ^{+1} ( ). Hence, we are done.  □

6Our formulation of Lemma 3.20 is actually equivalent to Danner’s Lemma 3.5 [Dan99]. He states instead (in our notation):

If I_{+1} I_{}, then for all , I_{}I_{}.

Letting := I_{}, his premise states that should be inflationary on . His conclusion can be reformulated to

for all ^{}^{}, I_{^{}}I_{^{}} where = + ^{}and = + ^{}. The new formulation is identical to the old since ordinal addition distributes over iteration in the following way:

I_{+} = I_{}I_{} This equation can be proven by transfinite induction on (note that ordinal addition is defined by recursion on the second argument) and holds without any assumptions on . The equation also appears in Danner’s Theorem 3.7, but only for monotone .

If is monotone and deflationary, ( ) , for the start value , then iteration will be antitonic in the ordinal index. This is, for instance, the case if we choose = , as we will do for the interpretation of .

Lemma 3.21 (Iteration of deflationary function) Let  𝔏 ^{+} 𝔏 and  𝔏

with ( ). Then

1. ^{}( ) ^{}( ) for , and

2. ^{}( ) ^{+1} ( ).

Proof. Analogously to Lemma 3.20. □

Summarizing, we can say that for a monotone which is inflationary (deflationary) for , we get a monotone (antitone) function ( ) = I_{}. In both cases, the limes inferior of at some limit ordinal coincides with the limes superior (lemmas 3.15 and 3.17), and, by definition of , with the actual value ( ) of at , hence is continuous at all limit ordinals.

3.3.3 Fixed points

By the theorem of Knaster and Tarski [Tar55], each monotonic operator 𝔏 𝔏 in a complete lattice 𝔏 has a least fixed point. This fixed point can be reached “from below” by transfinite iteration of , starting at the bottom element of the lattice. By Lemma 3.20, the iterates ^{}( ) form an ascending chain. If for some ordinal

( ^{}( )) ^{}( )

i.e., the -iterate is a prefixed point of , then the least fixed point of has been reached and we call the closure ordinal of operator .

Analogously, the greatest fixed point does exist which can be reached “from above” by starting at the top element of the lattice. By Lemma 3.21, the approximations ^{}( ) form a descending chain. For some ordinal it holds that

( ^{}( )) ^{}( )

i.e., the -iterate is a postfixed point of , and the greatest fixed point has been reached.

Cardinalities for pure kinds. Since each [[ ]]is a subset of the countable set ^{}by definition, the cardinality of [[ ]]is at most ℶ_{1} = (ℕ) , an uncountable cardinal number. With ℶ_{+1} we denote the cardinality of the power set (ℶ_{}) of the previous cardinal ℶ_{}. Let = be a pure kind, then [[ ]] ([[ _{1}]] [[ _{}]] [[ ]]) hence the following lemma holds:

Lemma 3.22 (Upper bound for cardinality) For pure kind ,

[[ ]] ℶ_{rk( )+1}

Proof. By induction on . Base case = follows by assumption. For the step case, let 1 and = .

[[ ]]  ([[ _{1}]]  [[ _{}]] [[ ]])  set-theoretic function space
(ℶ_{rk( _{1})+1}  ℶ_{rk( _{})+1} ℶ_{1})  induction hypothesis
(ℶ_{max rk( _{})+1 1} )  cardinal multiplication
ℶ_{1+max_{}rk( _{})+1}  definition of ℶ_{}
= ℶ_{rk( )+1}  definition of rank
□

Closure ordinal. At which ordinal will least and greatest fixed point be surely reached for any monotone operator? We can give a “brute-force” upper bound for as follows: Assume we want to construct a fixed point in lattice 𝔏 = [[ ]]for some by a chain ( _{}) of approximations. Since the cardinality of 𝔏 is bounded by ℶ_{}where = rk( ) + 1 (see Lemma 3.22), the chain can enumerate less then ℶ_{}elements _{}where 0 ℶ_{}. Hence, the element ℶ_{}must be the fixed point. An upper bound for the closure ordinal for all monotone operators in all lattices [[ ]]with pure kind is the supremum of all ℶ_{}, the ordinal ℶ_{}. Now we can complete the definition of [[ord]]setting

ord := ℶ_{}

3.3.4 Inductive and Coinductive Constructors

Now, we can fix the semantics of _{}and _{}. Recalling that [[ ]]_{}was defined as Sem( ), we set

Sem( _{})( )( ) := ^{}( ^{}) and
Sem( _{})( )( ) := ^{}( ^{})

Lemma 3.23 (Semantics of (co)inductive constructors fulfill specification) We have

\begin{matrix}[[ _{}]] & & [[ord]]^{+} ([[ ]]^{+} [[ ]]) ^{+} [[ ]] \\ [[ _{}]] & & [[ord]]^{}([[ ]]^{+} [[ ]]) ^{+} [[ ]] \end{matrix}

Proof. By definition and lemmata 3.19, 3.20, and 3.21. □

Theorem 3.24 (Soundness of folding and unfolding) Let _{}_{}_{}, [[ ]]^{+} [[ ]], and [[ord]]. We set

:= ([[_{}]] )  (unfolded) ,
:= [[_{}]]([[s]] )  (folded) .

Then ^{}and ^{}.

Proof. We consider the inductive case _{}= _{}, the case of coinductive constructors is proven analogously. Observe that = ^{+1} ( ) and = ^{[[s]]}( ). Since [[s]] = + 1 for ^{ord}, the only interesting case is = ^{ord}. Then,

[[s]] = ^{ord}, but still holds since ^{ord} ( ) is a fixed point of . □

The soundness of rules ty-fold and ty-unfold is a consequence of this theorem.

3.3.5 Soundness of -Dropping

The least fixpoint of a constructor equation

\begin{matrix}: \\ = \end{matrix}

can mechanically be expressed as _{}^{}. However, if is of a regular structure, the rank of the fixed-point can be decreased. For instance, the equation

List = 1 + List

has, besides the mechanical solution ^{}_{^{+}}  1 +  with a rank-2
fixed-point, the rank-1 solution  _{}^{}1 +  . The second constructor

has been obtained from the first by lambda dropping. With our semantics, we can prove that the two solutions describe the same lists. More generally, assume a constructor

Γ :ord : _{2} ^{+} _{1} ^{}_{2}

and a family of valuations ( ) := [  ] for some  [[Γ]]. Then for all

[[ord]],

[[ ^{}_{^{}}( ) ]]_{( )} = [[ _{_{2}}^{}]]_{( )}

The proof proceeds by transfinite induction on without difficulties.

3.4 Semantical Types

In this section, we give a generic term model for our calculus, showing that the typing rules are sound. Later we will instantiate this model to obtain a proof of strong normalization. A generic soundness proof can, for instance, be found in work of Vouillon [Vou04] and Melliès [VM04]. The idea is to consider types as closed sets of terms between a (minimal) set of neutral terms and a (maximal) set of safe terms. Informally a set is closed if for each of its terms it also contains all terms ^{}which behave the same as (for instance, weak head reducts of ). The result of the soundness proof is that each typable term is safe. Safe can mean different things: e.g., that the term evaluates without error; in our case a safe term will be a strongly normalizing one. Although we have taken some ideas from Vouillon and Melliès to structure our soundness proof, it needs to be stressed that their method does not directly apply, since we are interested in strong and not just weak normalization. For instance, we have to introduce the concepts of safe evaluation contexts and safe reduction. Matthes [Mat05] defines such safe contexts for a classical system F with sum types; safe evaluation is only implicit in his inductive definition of strongly normalizing terms.

Vaux [Vau04] and the author, in joint work with Coquand [AC05], have carried out a generic soundness proof where semantical types were not required to be closed sets. This was possible since in their model -equal terms were identified. From such a model, however, one can only harvest a proof of weak normalization. A proof of strong normalization cannot be extracted, since the property “strongly normalizing” is not preserved under -equality.^{7} Hence, we need to fall back to closed sets; in our case, we use a form of saturated sets [Tai75, Luo90], which are a variant of Girard’s reducibility candidates [GLT89].

In the following we will develop requirements for our model and exhibit them with labels with the prefix req .

Function space. Many models of the -calculus define the function space between sets of terms and as

:= for all

In other words, every term which behaves as a function—because it can be applied—is considered a function.^{8} The function space will be a closed set if is closed and is a set of safe terms.

Type interval. Each semantical type [[ ]] must contain only safe terms and contain all neutral terms. In the following, we assume a set Tm of safe terms and a set Tm of neutral terms such that

req- -sub-
req- -val  if  then ▷ Val

Herein, ▷ is a to-be-defined evaluation relation. One could think of ▷ as “ evaluates to without error”; then a choice for would be the terms whose evaluation does not throw an exception, but might diverge, and would contain the diverging terms. In our case ▷ will be a variant of weak head reduction, and will consist of the non-values which do not weak head reduce.

7If is strongly normalizing and Ω diverging, then ( _) Ω is -equal to but only weakly normalizing.

8Matthes [Mat00] calls this definition elimination based. The alternative is to define the function space introduction based as the closure of the set of all function constructions, in our case - abstractions, recursive and corecursive functions. The elimination-based approach has the obvious advantage of succinctness and spares us from defining a closure operator. The introduction-based approach, however, has other advantages: it provides a predicative semantics of disjoint sums [AA00] [Mat05, Sect. 4] or other constructions which have an elimination into an arbitrary type (e.g., unary sums as in the computational -calculus [LS05]).

Each semantical type will be in the interval [ ], i. e., . In the following we establish the requirements for to be an operator on term sets in this interval.

Safe evaluation contexts are isolated by the judgements Sframe and Scxt.

sf-app \frac{}{_Sframe}  sf-rec \frac{_{1}  _{}}{fix_{}^{}_{1}_Sframe}

sc-id \overline{Id Scxt}  sc-push \frac{Scxt  Sframe}{Scxt}

A strict function is one which is undefined for undefined arguments, or, which diverges if called with a diverging argument. We generalize “diverging” to “neutral” and call a function strict which maps neutral terms to neutral terms. Safe evaluation frames must be strict functions [Vou04], i. e.,

req-strict  ( ) for all Sframe

A trivial consequence is that all safe evaluation contexts are strict as well.

Lemma 3.25 (Function space is above ) If  and  then

.

Proof. Since req-strict can be rewritten as ^{1} ( ) for all Sframe, the lemma becomes obvious if rewrite the definition of function space to

= _{}(_)^{1} ( )

(By sf-app we have  for all  , hence,  (_)^{1} ( ).)

Alternatively, the lemma follows from monotonicity of function space, since

req-strict implies  .  □

Vouillon [Vou04] defines the function space as the set of safe terms which behave as a function. In our model instance, all functions will turn out to be safe, hence, we make this a requirement.

req-fun-safe

(This condition is one property of what Vaux [Vau04] calls a stable pair ( ).)

Lemma 3.26 (Functions are safe) If  and  then .

Proof. Since, the function space construction is contravariant on its domain and covariant on its codomain, the lemma follows directly from req-fun-safe .

□

Summing up, the requirements guarantee that function space remains within the type interval, i. e., [ ] [ ] [ ].

3.4.1 Saturation

In this section, we axiomatize the evaluation relation ▷ and define a generic notion of saturated set.

Safe weak head reduction. We assume a relation ▷ on terms with the following properties.

req-  ( )  ▷ [ ]  if
req-rec  fix_{}^{}_{1} ▷ (fix_{}^{}) _{1}  if = fix_{^{}}^{}^{}_{1 ^{}}
req-corec  (fix_{}^{}_{1}) ▷ ( (fix_{}^{}) _{1})  if = fix_{^{}}^{}^{}_{1 ^{}}_
req-ecxt  ( ) ▷ ( ^{})  if ▷ ^{}
req-trans  ▷ is transitive

The least relation satisfying these requirements would be weak head reduction if we omitted the side condition in req- . In the presence of this condition, thinking of as the set of strongly normalizing terms, two related terms behave equivalently with respect to strong normalization.^{9} Consequently, we require that is closed under ▷ in both directions.

req- -closed  If  and ▷ ^{}or ◁ ^{}then ^{}

Remark 3.27 Here, we give another justification that we need to prevent fixedpoint unfolding in a term of the shape fix^{}(fix^{}^{}). Assume there were no side conditions on the reduction rules for fixed points. Let = _and = fix^{}id _. Then

( (fix^{}))  ( ) neutral, but
(fix^{})  ^{+}  (fix^{}) diverging

Hence, the rolled and unrolled version do not behave the same, and at least the rule req-corec would be unsound.

Saturated sets. A set is saturated, SAT, if and is closed under ▷-reduction and -expansion.

Remark 3.28 If is a set of safe terms and closed under ▷-reduction, then property req- -val is inherited from to . This holds especially for SAT.

Lemma 3.29 (Function space is closed) If is closed, then so is .

9In the absence of the side condition, [ ] could be strongly normalizing while ( ) is not (if FV( )). The side condition can also be meaningful in different contexts. E. g., if “safe”

means “evaluating without error” [Vou04, VM04], and evaluates to an error, then the -reduction ( ) ▷ [ ] is not semantics-preserving in call-by-value languages.

Proof. Let  . For ^{}▷ we show ^{}by assuming an
arbitrary  and deriving ^{}. But this follows from  , since both

▷ by req-ecxt and is closed under ▷-expansion. In the same way, closure under ▷-reduction is inherited from to . By the previous remark, we are done. □

Corollary 3.30 (Function space is saturated) If and SAT then SAT.

Proof. By the previous lemma, the function space is closed. It is between and by lemmata 3.25 and 3.26. □

Corollary 3.31 (Abstractions are functions) Let  SAT. If [ ]  for
all  , then  .
Proof. For  we have to show ( )  . This follows from

( ) ▷ [ ] , since is closed under ▷-expansion. □

3.4.2 Admissible Types for Recursion

In the last section, we have established that semantic types model abstraction and application. Now we turn our attention to the recursion combinators that extend the -calculus.

Let O be an initial segment of the ordinal numbers.

Admissible semantic types for recursion. The semantic type family O SAT is admissible for recursion on the + 1st argument if

adm- -shape  ( ) = _{}( _{1}( ) ( ) ( ))

for some index set

and _{1} _{}O SAT

adm- -start ( 0) for all and
adm- -limit  inf_{}( ) ( ) for all limits 0 = O

For the soundness of this criterion we need a recursive function applied to a corecursive value to be neutral.

req-fix^{}fix^{}fix_{}^{}_{1}(fix_{^{}}^{}^{}_{1 ^{}}^{}) if ^{}{ \atop ^{}}

However, now there are closed neutral terms, which is quite uncommon. This means that semantically, all types are inhabited by closed terms, which in turn means that we cannot use this semantics to show that the type theory is consistent. More concretely, we cannot show that does not have closed inhabitants. But this is not important for strong normalization.

A summary of accumulated requirements is given in Table 3.1.

Cat. Page Requirement
62  req- -sub-
63 req-strict Scxt( )
65  req-fix^{}fix^{}fix_{}^{}_{1}(fix_{}^{}^{}_{1}^{})
62  req- -val  if  then ▷
63  req-fun-safe
64  req- -closed  ▷  ▷
▷ 64  req-  ( ) ▷ [ ]
64  req-rec  fix_{}^{}_{1} ▷ (fix_{}^{}) _{1}
64  req-corec  (fix_{}^{}_{1}) ▷ ( (fix_{}^{}) _{1})
64  req-ecxt  if ▷ ^{}then ( ) ▷ ( ^{})
64  req-trans  ▷ is transitive

Table 3.1: Summary of requirements.

Lemma 3.32 (Recursion is a function) Let O SAT be admissible for recursion on the + 1st argument. If ( ) ( + 1) for all + 1 O, then fix_{}^{}( ) for all O.

Proof. By transfinite induction on O.

The limit case is a direct consequence of adm- -limit .

For the remaining cases, using adm- -shape , assume , _{}_{}( ) for 1 , and ( ) and show fix_{}^{}( ). Since all _{}are safe and is safe by assumption, := fix_{}^{}_is a safe evaluation frame. Hence, if , then ( ) ( ), and in case = 0 we are done, since, by adm- -start , the set ( 0) contains only neutral terms.

Finally, we consider = + 1 and ▷ . If = fix_{^{}}^{}^{}_{1 ^{}}^{}, then ( ) ( + 1) by req-fix^{}fix^{}. Otherwise, note that (fix_{}^{}) ( + 1) by assumption and induction hypothesis. Since ( ) ▷ ( ) ▷ (fix_{}^{}) ( + 1), we conclude by closure of ( + 1) under ▷-expansion. □

3.4.3 Refined Saturation

In this section, we will refine our notion of saturation, to prepare for the treatment of corecursion.

Orthogonality. An orthogonality relation between term and evaluation context is given by

: ( )

For a set of terms we can compute its orthogonal, the set of evaluation context in which all terms behave well, i. e., evaluate safely. In another iteration, we take the orthogonal of this set of evaluation contexts, i. e., all terms which behave well in all contexts , and arrive at the biorthogonal of the original term set. The biorthogonal is closed and can serve as a semantical type—this idea is implicit in Girard’s semantics of linear logic and resurfaces in Ludics [Gir01]. Girard has not written up the idea clearly himself, but it slowly spread in the (French) research community. Parigot [Par97, page 1469] defines a saturated set (which is a semantical type in the context of strong normalization proofs) as a set of terms that are strongly normalizing when applied any list of strongly normalizing terms contained in a certain set of term lists. Applying to a list of terms is a special case of putting into an evaluation context—hence, Parigot effectively uses Girard’s technique (without reference), albeit not the intuition of orthogonality. Matthes [Mat05] builds on the work of Parigot and extends it to arbitrary evaluation contexts. A nice presentation of orthogonality can be found in the recent work of Vouillon [Vou04] and Melliés [VM04]—-this is where I draw my terminology from. However, they do not show strong normalization; I had to add the concept of safe evaluation context to make it work in my case. Recently, Lindley and Stark [LS05] have used biorthogonality to show strong normalization of the computational -calculus and they refer to Andrew Pitts. In personal communication, Andrew Pitts claimed to have invented the technique independently of the French School.

After having given honor to our teachers, we now can define:

:=  Tm  for all  for Ecxt
SAT^{}:=  Id  Scxt
SAT :=  ^{}SAT^{}
:= Scxt^{}

Note that (_)^{}is an antitonic operation. Since = Id ^{}it is clear that is the greatest and the least saturated set.^{10} By definition, the set of neutral terms also fulfills the requirements req- -sub- and req-strict . The requirement req-fix^{}fix^{}is now phrased in terms of :

req-fix^{}fix^{}(fix_{}^{}_{1}(fix_{^{}}^{}^{}_{1 ^{}}^{})) for all Scxt

Lemma 3.33 ( ^{}is closed) If for ^{}it holds that ▷ ^{}or ^{}▷ , then ^{}^{}.

Proof. We need to show ( ^{}) for all . This holds since ▷ is closed under evaluation contexts and is closed under ▷. □

Corollary 3.34 The new notion of SAT is a refinement of the old one.

We need to show that the function space is still an operation on SAT.

Lemma 3.35 (Function space in SAT) If and SAT then SAT.

10The converse, ^{}= Id is not true if we let be the set SN of strongly normalizing terms:

Because SN implies SN for any variable , we have (_) SN^{}.

Proof. Let ^{}= . By definition, = ^{} ˆ with ˆ := (_) and Scxt. Since ( ) = by req-fun-safe , we have = ^{} ˆ Id ^{}= ( ˆ Id )^{}. The last step is formally proven in Lemma 3.38. □

For the semantical justification of the typing rule for corecursion, which will be given in the next section, we require fix^{}to be safe, if applied to a number of safe arguments up to its arity.

req-fix^{}fix_{}^{}^{+1}

The remaining requirements are displayed in Table 3.2.

Cat. Page Requirement
67  req-fix^{}fix^{}Scxt(fix_{}^{}_{1}(fix_{}^{}^{}_{1}^{}))
62  req- -val  if  then ▷
63  req-fun-safe
64  req- -closed  ▷  ▷
68  req-fix^{}fix_{}^{}^{+1}
▷ 64  req-  ( ) ▷ [ ]
64  req-rec  fix_{}^{}_{1} ▷ (fix_{}^{}) _{1}
64  req-corec  (fix_{}^{}_{1}) ▷ ( (fix_{}^{}) _{1})
64  req-ecxt  if ▷ ^{}then ( ) ▷ ( ^{})
64  req-trans  ▷ is transitive

Table 3.2: Summary of refined requirements.

A bit surprisingly, corecursive values can be found in :

Lemma 3.36 (Neutral corecursive values) neutral corecursive values If _{1} and (fix_{}^{}) _{1} then := fix_{}^{}_{1} .

Proof. We have to show that ( )  for all  Scxt. In case = Id,

we have by req-fix^{}. Otherwise = ^{}. Either is a recursive function, then ^{}( ( )) is safe by req-fix^{}fix^{}, or is an applicative evaluation frame and ^{}( ( )) ▷ ^{}( ( (fix_{}^{}) _{1})) which is neutral by assumption and req-strict , hence, ^{}( ( )) by Lemma 3.33. □

An example for such a neutral term is fix_{0}^{}_

3.4.4 Admissible Types for Corecursion

Admissible semantic types for corecursion. The semantic type family O SAT is admissible for corecursion with arguments if

adm- -shape  ( ) = _{}( _{1}( ) ( ))

for some index set and _{1} O SAT

adm- -start ( 0) for all and
adm- -limit  inf_{}( ) ( ) for all limits 0 = O

Lemma 3.37 (Corecursion is a function) Let O SAT be admissible for corecursion with arguments. If ( ) ( + 1) for all + 1 O, then fix_{}^{}( ) for all O.

Proof. By transfinite induction on O.

The limit case is a direct consequence of adm- -limit .

For the remaining cases, using adm- -shape , assume , _{}_{}( ) for 1 and show := fix_{}^{}( ). Note that and _{}are safe, hence, by req-fix^{}. Since ( 0), we are done in case of = 0.

For case = + 1, let Scxt be a set of evaluation contexts such that = ( + 1). Assume an arbitrary and show ( ) . If = Id, there is nothing new to show, otherwise = ^{}. If = fix_{^{}}^{}^{}_{1 ^{}}_, then ( ) by req-fix^{}fix^{}. Otherwise, note that (fix_{}^{}) ( + 1) by assumption and induction hypothesis. Since ( ) ▷ ( (fix_{}^{})) , we conclude by closure of . □

3.4.5 Lattice of Saturated Sets

In this section we will establish that SAT is a complete lattice of sets. This will justify the interpretation of universal quantification as intersection and enable the choice [[ ]]:= SAT. Since for SAT, we set ^{}:= .

De Morgan laws. The orthogonality operation ^{}is an intuitionistic negation. The following de Morgan laws hold:

Lemma 3.38 (De Morgan) Let some non-empty index set and _{}Ecxt for all . Then,

\begin{matrix}_{}_{}^{} & = & ( _{}_{})^{}and \\ _{}_{}^{} & & ( _{}_{})^{} \end{matrix}

Proof.

_{}^{}for all for all _{}
for all  _{}_{}
( _{}_{})^{}
_{}^{}=  for some  for all  _{}
=  for all  _{}_{}
=  ( _{}_{})^{}
□

The de Morgan laws can also be read topologically: Let the closed term sets be the saturated ones. Then intersections of closed sets (even infinite intersections), are still closed, whereas this need not hold for unions. In the following we show by example that the missing de Morgan law does indeed not hold.

Lemma 3.39 (Orthogonality not classical) Let the set of safe terms contain exactly the strongly normalizing ones. There are _{1} _{2} Ecxt such that ( _{1} _{2})^{} _{1}^{}_{2}^{}.

Proof. Let :=  and ^{}:=  , _{1} := Id (_) , and _{2} := Id (_^{})

Then ( _{1} _{2})^{}= Id ^{}= , and the normal term is safe. But _{1}^{}, since

, and  _{2}^{}, since ^{}^{}^{}^{}.  □

Remark 3.40 (Maximal sets of contexts) This counterexample is not completely satisfying, because _{1}^{}= _{2}^{}, hence, _{1} and _{2} are just incompatible representations of the same saturated set . This suggests that the representation of a saturated set should be the biggest set of contexts such that ^{}= . Whether such maximal sets would satisfy the missing de Morgan law, is unclear to me and left as an open question.

As a consequence of the de Morgan laws, saturated sets form a complete lattice.

Corollary 3.41 (SAT closed under intersection) If 𝔄 SAT, then 𝔄 SAT.

Proof. If 𝔄 is empty, we set 𝔄 = . Otherwise, let _{0} := ^{}𝔄 . Then _{0} SAT^{}and _{0}^{}= 𝔄. □

Since is the least saturated set, ^{}= SAT = .

It follows that ([[ ]] ⨅^{}^{}) := (SAT ) is a complete lattice of sets and can serve as basis for our model of kinds, constructors, and subtyping as developed in Section 2.3. Soundness of the subtyping rule ty-sub is an immediate consequence of Theorem 2.27. Setting the interpretation of quantification to

[[ _{}]]_{}( ) = Sem( _{})( ) := _{[[ ]]} ( )

soundness of the generalization and instantiation rules ty-gen and ty-inst , follows immediately.

Supremum. The supremum of the lattice [[ ]]is formally defined as

_{}^{}_{}:= ⨅^{}SAT  ^{}_{}for all
=  ^{}SAT^{}and ^{}_{}for all

Vouillon [Vou04] presents another definition of the union of semantical types. Let

:=  Scxt  for all

for a set of terms . For reasons of symmetry, the de Morgan laws hold for ^{} as for ^{}. Since for Tm and Scxt, the two orthogonality operations form a Galois connection between sets of terms ( (Tm) ) ordered by inclusion and sets of safe evaluation contexts (Scxt ) ordered by the superset relation (see Appendix C). Hence, the function which maps Tm to

\overline{}:= ^{}

is a closure operator on sets of terms.

Lemma 3.42 If then ^{}SAT^{}and \overline{}SAT.

Proof. If  then Id ^{}. Furthermore ^{}Scxt by definition.  □

We can now define union of term sets 𝔄 as follows:

𝔄 := \overline{𝔄}

Remark 3.43 The closure operation plays a crucial role when we construct the semantics of inductive types. Consider the approximations at^{}of the semantical type of natural numbers. For , at^{}contains only bounded numbers, which can be characterized by a set of finite observations . But at^{} cannot be characterized by finite observations alone; recursive evaluation contexts (like the identity function on Nat) are required. These come in through the closure operation that is involved in the supremum: at^{}= _{}at^{}.

Lemma 3.44 Let be some index set and _{}for all . Then

_{}^{}_{}= _{}_{}

Proof. Note that (*) ( _{}_{})^{}SAT^{}by Lemma 3.42.

_{}^{}_{}=  ^{}SAT^{}and ^{}_{}for all  definition
=  ^{}SAT^{}and  _{}^{}for all  Galois conn.
=  ^{}SAT^{}and  _{}_{}^{}
=  SAT^{}and ( _{}_{})^{}^{}de Morgan
=  _{}_{})^{}(*)
= _{}_{}definition
□

The supremum of saturated term sets is the closure of their set-theoretical union, but not necessarily identical to it, which is the case for the more traditional notion of saturation as found in Section 3.4.1 and in, e. g., Luo [Luo90], Altenkirch [Alt93, AA00], Matthes [Mat98, Mat00], Barthe et al. [BFG^{+} 04], and previous work of the author [Abe03, Abe04].

We have now given a semantical justification for each typing rule. We will assemble these pieces in the next section, where we give a term model of our calculus.

3.5 Soundness of Typing

3.5.1 Admissible Types for Recursion, Syntactically

Having a semantical characterization of admissible types for recursion we can turn it into a syntactical one. For now, we give a simple characterization: A recursive function goes from an inductive type to a result type which depends monotonically on the ordinal index. This is the shape of types from Barthe et al. [BFG^{+} 04] and from previous work of the author [Abe04]. Examples would be Nat^{}and List^{}Nat^{}, where does not depend on the ordinal index . Excluded would be types like Nat^{}Stream^{}(since Stream^{}is antitone in ) or Nat^{}Nat^{}Nat^{}, the latter being the type of the maximum function. Since we also have inductive constructors, the general shape of the recursive argument is ^{}. Then we allow the recursive function to be a natural transformation, i. e., of the shape : ^{}^{}( _{1} ) ( _{}) . Of course, we can quantify over several constructor variables, arriving at the shape : ^{}^{}( _{1} ) ( _{}) , or, using the abbreviation for natural transformations, at ( ^{}) . As a final relaxation, we do not require the inductive argument to be the first one. The function may have parameters before the inductive argument, but their types must be antitone in the ordinal index.

Γ fix_{}^{}-adm :  Γ :ord  = ( ( ^{}) ) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ :+ ord : ^{}for some ^{}= ^{} Γ : ord _{}: ^{}for 1 and Γ _{}: ^{}_{}for 1

We now prove this criterion sound. To this end, we will make use of the semantics of declarative kinding and equality (see Section 2.3).

Lemma 3.45 (Soundness of admissible recursion types) If Γ fix_{}^{}-admand [[Γ]], then [[ ]]_{}is admissible for recursion on the + 1st argument, where O may be any initial segment of [[ord]].

Proof. Since Γ :ord  = ( ( ^{}) ) : and  FV( ), we know

by Thm. 2.27 that for each O,

[[ ]]_{[ ]} = [[ ]]_{}( ) = [[ ( ^{}) ]]_{[ ]} [[ ]]= SAT

Hence, := [[ ]]_{}O SAT. In the following, we verify the conditions adm- -shape , adm- -start , and adm- -limit . adm- -shape Show ( ) = _{}_{1}( ) ( ) ( ). We set

:= [[ _{1}^{}]]  [[ _{}^{}]]  where := ^{}
( ) := [[ _{}]]_{[ ]} for 1
( ) := (I_{}[[ ]]_{}^{})([[ _{1}]]_{}) ([[ _{}]]_{})  where := and
( ) := [[ ]]_{[ ]}

adm- -start Show ( 0) . This is clear since I_{0} [[ ]]_{}^{}= ^{}and 1 _{}= ^{}= for any .

adm- -limit Show inf_{}( ). We assume inf_{}and prove

1( ) ( ) ( )

To this end, fix arbitrary _{}_{}( ) and ( ). By Lemma 3.15, the inductive type at a limit ( ) = sup_{}( ), hence ( ) for some . Since Γ : ord _{}: ^{}, the families _{}( _) are antitone, hence _{}_{}( ). Together, ( ) ( ) by monotonicity of ( _), which we obtain from Γ :+ ord : ^{}. □

3.5.2 Admissible Types for Corecursion, Syntactically

Similarly to the admissible types for recursion one can motivate the ones for corecursion. The most important requirement is that the result type of a corecursive function must be coinductive. In essence, our rule is the one of Barthe et al. [BFG^{+} 04], lifted to coinductive constructors and natural transformations.

Γ fix_{}^{}-adm :  Γ :ord  = ( ( ^{}) ) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ : ord _{}: ^{}(all ) for some ^{}= ^{}and Γ _{}: ^{}_{}for 1

Lemma 3.46 (Soundness of admissible corecursion types)  If Γ  fix_{}^{}-adm

and [[Γ]], then [[ ]]_{}is admissible for corecursion with arguments (where O may be any initial segment of [[ord]]).

Proof. Since Γ : ord  = ( ( ^{}) ) : and  FV( ), we know

by Thm. 2.27 that for each O,

[[ ]]_{[ ]} = [[ ]]_{}( ) = [[ ( ^{}) ]]_{[ ]} [[ ]]= SAT

Hence, := [[ ]]_{}O SAT. In the following, we verify the conditions adm- -shape , adm- -start , and adm- -limit . adm- -shape Show ( ) = _{}_{1}( ) ( ). We set

:= [[ _{1}^{}]]  [[ _{}^{}]]  where := ^{}
( ) := [[ _{}]]_{[ ]} for 1  and
( ) := (I_{}[[ ]]_{}^{})([[ _{1}]]_{}) ([[ _{}]]_{})  where :=

adm- -start Show ( 0). This is clear since I_{0} [[ ]]_{}^{}= ^{}and 1 _{}= ^{}= for any .

adm- -limit Show inf_{}( ). We assume inf_{}and prove

1( ) ( )

To this end, fix arbitrary _{}_{}( ) and show ( ). By Lemma 3.17, the coinductive type at a limit ( ) = inf_{}( ), hence, we need to show ( ) for arbitrary . Since Γ : ord _{}: ^{}, the families _{}( _) are antitone, hence _{}_{}( ). Together, ( ) by assumption. □

3.5.3 Soundness Proof

Valuations. For the remainder of this chapter, we consider valuations (TyVar Var) ( _{}[[ ]] Tm) which map constructor variables to semantical constructors [[ ]] for some and term variables to terms. Since a constructor does not depend on term variables, it is easy to see that [[ ]]_{}= [[ ]]_{↾TyVar}. The denotation ⦇ ⦈_{}of a term under a valuation is defined as follows:

⦇ ⦈_{}:=
⦇ ⦈_{}:= ( )
⦇ ⦈_{}:= ⦇ ⦈_{}⦇ ⦈_{}
⦇ ⦈_{}:=  ⦇ ⦈_{[ ]}  if is singular in ⦇ ⦈_{}
By singular in ⦇ ⦈_{}, we mean that  FV( ( )) for any  FV( ) which is

different from .^{11} Singularity is important to avoid variable capture in terms of the substitution by the -abstraction, which has moved to the outside. We can express singularity by the equivalent condition FV⦇ ⦈_{}. Note that singularity can always be achieved by renaming of the bound variable , since FV⦇ ⦈_{}is finite.

Lemma 3.47 (Substitution for singular variable) If is singular in ⦇ ⦈_{}, then we have [ ]⦇ ⦈_{[ ]} = ⦇ ⦈_{[ ]}.

Proof. By induction on . □

11This is the variable condition in the corresponding part of Barthe et al. [BFG^{+} 04].

Sound valuations. We define the proposition [[Γ]]by recursion on Γ.

[[ ]]  :  true
[[Γ : ]] :  [[Γ]]and ( ) [[ ]]
[[Γ : ]] :  [[Γ]]and ( ) [[ ]]_{}

This notion is compatible with [[Δ]]from Section 2.3: If Δ is the restriction of Γ to constructor variable declarations, then [[Γ]]implies [[Δ]].

Lemma 3.48 (Sound context lookup) If Γ cxt and both ( : ) Γ and [[Γ]] then ( ) [[ ]]_{}[[ ]].

Proof. By induction on Γ cxt, using Lem. 2.20. □

Theorem 3.49 (Soundness of typing) If Γ : and [[Γ]]then ⦇ ⦈_{}[[ ]]_{}.

Proof. By induction on the typing derivation.

Case

ty-var \frac{( : ) Γ  Γ cxt}{Γ  :}

By Lemma 3.48, since ⦇ ⦈_{}= ( ).

Case

ty-abs \frac{Γ :  :}{Γ  :}

Let := [[ ]]_{}and := [[ ]]_{}. Since, by Lemma 3.4, the context Γ : is wellformed, we have by Lemma 3.48 that SAT. Likewise, SAT by Lemma 2.20, since Lemma 3.5 entails Γ : . W. l. o. g., is singular in ⦇ ⦈_{}. To show that ⦇ ⦈_{}= ⦇ ⦈_{[ ]} , by Corollary 3.31 it is sufficient to show [ ]⦇ ⦈_{[ ]} for arbitrary . This, however, follows from the induction hypothesis, since [ ] [[Γ : ]], and [ ]⦇ ⦈_{[ ]} = ⦇ ⦈_{[ ]} by Lemma 3.47.

Case

ty-app \frac{Γ  :  Γ  :}{Γ  :}

Let := [[ ]]_{}and := [[ ]]_{}. By induction hypothesis, ⦇ ⦈_{} and ⦇ ⦈_{}, thus ⦇ ⦈_{}= ⦇ ⦈_{}⦇ ⦈_{}by definition of the function space.

Case

ty-gen \frac{Γ :  :}{Γ  : _{}}FV( )

By definition of [[ _{}]], we have to show ⦇ ⦈_{}[[ ]]_{}( ) for all [[ ]]. This follows by induction hypothesis, since [ ] [[Γ : ]], and [[ ]]_{[ ]} = [[ ]]_{}( ) because FV( ).

Case

ty-inst \frac{Γ  : _{}Γ  :}{Γ  :}

By induction hypothesis, ⦇ ⦈_{}_{[[ ]]} [[ ]]_{}( ) and [[ ]]_{}[[ ]]. Hence ⦇ ⦈_{}[[ ]]_{}.

Case

ty-sub \frac{Γ  :  Γ  :}{Γ  :}

By induction hypothesis ⦇ ⦈_{}[[ ]]_{}, which is a subset of [[ ]]_{}by Lemma 2.20.

Case

ty-fold \frac{Γ  : ( _{}) }{Γ  : _{}( + 1) }
By Lemma 3.5 we have Γ  ( _{}) : , which entails Γ  : +
and Γ  : ord, as well as Γ  _{}: _{}for 1  , if we define

:= . Hence, := [[ ]]_{}[[ ]] ^{+} [[ ]]and := [[ ]]_{}[[ord]]and we can conclude by Theorem 3.24.

Case

ty-unfold \frac{Γ  : _{}( + 1) }{Γ  : ( _{}) }

Analogously to case ty-fold .

Case

ty-rec \frac{Γ fix_{}^{}-adm Γ  : ord  Γ cxt}{Γ fix_{}^{}: ( :ord  ( + 1))}

By lemmata 3.45 and 3.46 the family := [[ ]]_{}[[ord]] [[ ]]is admissible for (co)recursion. We assume _{[[ord]]} ( ) ([[s]] ) which entails that ( ) ( + 1) for all ^{ord}. By lemma 3.32 resp. 3.37 we conclude fix_{}^{}([[ ]]_{}). □

A consequence of soundness is that all typable terms are safe, if variables are neutral.

Corollary 3.50 (Typable terms are safe) Assume Var  . If Γ  : then

.

Proof. Let be a valuation with ( ) = ^{}for all ( : ) Γ and ( ) = for all ( : ) Γ. Since [[ ]]_{}, the valuation is sound w. r. t. context Γ. Soundness of typing entails = ⦇ ⦈_{}[[ ]]_{}. □

3.6 Strong Normalization

In this section, we will instantiate the set of safe terms by an inductively defined set SN of strongly normalizing terms and harvest a proof of strong normalization from the soundness proof of typing.

3.6.1 A Few Remarks on the Method

The usual (classical) definition of strongly normalizing terms is: those terms, which have no infinite reduction sequences. This definition has quite nice closure properties, which are intuitively obvious: for example, if a term has no infinite reduction sequences, then this is true for all of its subterms as well. Defining as the set of (classically) strongly normalizing terms, we see immediately that req-fun-safe , , holds for non-empty : If , then is strongly normalizing for any , hence, is strongly normalizing.

Barthe et al. [BFG^{+} 04] use this definition of strong normalization, albeit in a positive formulation. For us, this is not sufficient, since we also require that all non-neutral terms in reduce to a value. Usually, after having shown strong normalization, this fact is a consequence of type preservation (subject reduction) and progress [Pie02]. But we need it already to show strong normalization.

Why do we require this and Barthe et al. do not? Because we are working in an equi-recursive system where an inhabitant of ^{}can be of any shape. Hence, a recursive function is unrolled when it is applied to any value. In an iso-recursive system, which is used in far more normalization proofs [AA00, Abe03, Abe04, Mat05] a canonical inhabitant of ^{}is of the form in where in is a constructor. The semantics of ^{}can be defined as those terms which are neutral or reduce to in for some . A recursive function : ^{} is only unrolled when applied to a constructor. In the normalization proof, when looking at we know that [[ ^{+1} ]]is either neutral or reduces to in . Then we can unroll the recursive function and conclude the reasoning by induction hypothesis [Abe04, Thm. 5.10]. Similarly, in Lemma 3.32 we need to know that reduces to a value, but since ^{+1} = ( ^{}) can be any type (product type, function type, polymorphic type etc.), we need to know that the non-neutral inhabitants of all semantical types reduce to a value. This is most directly achieved by requiring that it holds for all safe terms.

A byproduct of this decision is that we also get more in the end: We not only exclude non-termination; non-neutral terms also do not get stuck. Hence, we get both strong normalization and progress.

The search for a suitable definition of lead us to an inductive characterization of strongly normalizing terms. For the lambda calculus, this was first given by van Raamsdonk et al. [vRS95, vRSSX99], but it was already implicit in Goguen’s work on typed operational semantics [Gog94, Gog95, Gog99]. Joachimski and Matthes used it to give a combinatorial normalization proof for the simply-typed -calculus [JM03], and Matthes extended it to other calculi [Mat98 Mat00 Mat05].

3.6.2 Inductive Characterization

We set := SN and ▷ := _{SN}^{}both of which will be defined below.

Strong(-ly normalizing) head reduction _{SN} ^{}is defined inductively by the following rules.

shr- \frac{SN}{( ) _{SN} [ ]}  shr-frame \frac{_{SN} ^{}}{( ) _{SN} ( ^{})}

shr-rec \overline{fix_{}^{}_{1}  _{SN} (fix_{}^{}) _{1}}  = fix_{^{}}^{}^{}_{1 ^{}}^{}

shr-corec \overline{fix_{}^{}_{1}  _{SN} (fix_{}^{}) _{1}}

Note that due to the additional argument , the last rule is just short for

shr-corec \overline{(fix_{}^{}_{1}) _{SN} ( (fix_{}^{}) _{1})} = fix_{^{}}^{}^{}_{1 ^{}}^{}_

The crucial property is that the strong head expansion of a strongly normalizing term is strongly normalizing as well. The reflexive-transitive closure of strong head reduction fulfills the desired properties of ▷ from Section 3.4.1.

Lemma 3.51 ( _{SN} is deterministic) If ::  _{SN} ^{}and  _{SN} ^{}then

= ^{}.

Proof. By induction on . □

Lemma 3.52 (req-ecxt ) If _{SN}^{+} ^{}then ( ) _{SN}^{+} ( ^{}).

Proof. From shr-frame by induction on and _{SN}^{+}. □

Corollary 3.53 The relation ▷ := _{SN}^{}fulfills the five requirements req- , req-rec , req-corec , req-ecxt , and req-trans .

Strongly neutral terms SNe are defined inductively by the following rules.

sne-var \overline{SNe}  sne-frame \frac{SNe  Sframe}{( ) SNe}

sne-fix^{}fix^{}\frac{\begin{matrix} \\ fix_{}^{}_{1}_ \end{matrix}^{}Sframe  \begin{matrix} \\ fix_{^{}}^{}^{}_{1 ^{}}^{} \end{matrix}^{}SN}{( ) SNe}

Since the definition of Sframe rests on the definition of = SN, strongly neutral terms are defined simultaneously with SN below. Rule sne-fix^{}fix^{}fulfills requirement req-fix^{}fix^{}.

Strongly normalizing terms SN.

sn-sne \frac{SNe}{SN}  sn-abs \frac{SN}{SN}  sn-fix \frac{SN}{fix_{}^{}SN} + 1

sn-exp \frac{_{SN} ^{}^{}SN}{SN} sn-roll \frac{(fix_{}^{}) SN}{fix_{}^{}SN}

The set SN consists of strongly neutral terms (sn-sne ) and strongly normalizing values (sn-abs , sn-fix ) and is closed under strong head expansion (sn-exp ). Rule sn-fix fulfills requirement req-fix^{}. The rule sn-roll is admissible, but we have explicitely added it to simplify the proof of requirement req-fun-safe (see below).

Lemma 3.54 (SN is closed under ▷-expansion) If _{SN}^{}^{}and ^{}SN then SN.

Proof. By rule sn-exp . □

It is clear that SN is also closed under ▷-reduction.

Lemma 3.55 (SN is closed under ▷-reduction) If  SN and  _{SN}^{}^{}then

SN.

Proof. By induction on _{SN}^{}^{}. If the reduction sequence is empty (in case = ^{}), there is nothing to show. Otherwise, we perform case analysis on SN. The only rule which introduces redexes is sn-exp .

sn-exp \frac{_{SN} ^{}^{}SN}{SN}

Since _{SN} is deterministic, the first reduction in the sequence _{SN}^{+} ^{}is SN ^{}. Thus, ^{}SN follows by induction hypothesis. □

Thus, SN fulfills requirement req- -closed .

In contrast to the definition of strong normalization as the absence of infinite reduction sequences, the inductive characterization of SN also guarantees that every SN reduces to a weak head value, i. e., there are no stuck nonneutral terms.

Lemma 3.56 (SN is weak head normalizing) If SN then either ▷ ^{}SNe or ▷ Val SN.

Proof. By induction on SN. If the last rule was sn-exp , we proceed by induction hypothesis. All other rules introduce neutral terms or values. □

Let ^{▷} := ▷ ^{}with ^{}be the closure of a term set under ▷-expansion.

Lemma 3.57 (Neutral terms) ^{▷}SNe .

Proof. Recall that = Scxt^{}. Assume ▷ ^{}SNe and Scxt and show ( ) SN. Since ( ^{}) SNe by iterated application of sne-frame and SNe SN by rule sn-sne , it follows that ( ^{}) SN. Because ( ) ▷ ( ^{}) and SN is closed under ▷-expansion, ( ) SN. □

In particular, all variables are in , which is a precondition of Cor. 3.50. Putting the last two lemmata together, we see that every term in reduces to a strongly normalizing value SN under strong head reduction. Hence, SN fulfills req- -val .

Remark 3.58 ( = ^{▷}SNe) The proposition ^{▷}SNe, which complements Lemma 3.57, does not hold: In Lemma 3.36 we have shown that some corecursive values inhabit , but they are not in SNe. (If not for req-fix^{}fix^{}, this proposition would hold: We could show that no value can be safely inserted into all safe contexts by exhibiting a safe context = fix_{0}^{}( ) _ in which all values would loop, even the strongly normalizing ones.)

In the following we show validity of req-fun-safe , i. e., SN if SN for all .

Lemma 3.59 (Extensionality) If ::  SN or ::  SNe then SN.

Proof. By induction on .

Case

sne-frame \frac{SNe}{SNe}

By sn-sne , SN.

Case Let = .

sne-frame \frac{SN}{fix_{}^{}SNe}

By sn-fix , fix_{}^{}SN.

Case

sn-sne \frac{SNe}{SN}

By induction hypothesis.

Case

sn-fix \frac{SN}{fix_{}^{}SN}

Then fix_{}^{}SN by sn-fix .

3.6. STRONG NORMALIZATION 81

Case

sn-exp \frac{( ) _{SN}  SN}{( ) SN}

Since SN, SN by sn-abs . Case

sn-exp \frac{fix_{}^{}_{SN} (fix_{}^{})  (fix_{}^{}) SN}{fix_{}^{}SN}

By induction hypothesis, (fix_{}^{}) SN. Hence, fix_{}^{}SN by sn-roll . Case

SN ^{} ; \overline{shr-frame} ; _{SN} ^{}^{}SN
\overline{sn-exp}

SN

By induction hypothesis, ^{}SN, hence SN by sn-exp . Case

sn-roll \frac{(fix_{}^{}) SN}{fix_{}^{}SN}

By induction hypothesis (fix_{}^{}) SN, hence, fix_{}^{}SN by sn-roll . Case

sn-roll \frac{(fix_{}^{}) SN}{fix_{}^{}SN}

Then fix_{}^{}SN by sn-fix .

□

Corollary 3.60 (req-fun-safe ) SN SN. Proof. SN for all SN SN by the lemma. □

By Cor. 3.50, each typable term is in SN. What remains to show that if SN then indeed admits no infinite reduction sequences.

3.6.3 Soundness of the Inductive Characterization

Classically, a term is strongly normalizing if there are no infinite reduction sequences starting with . Constructively, the set of strongly normalizing terms sn is the accessible part of Tm w. r. t. the one-step reduction relation. Hence, it can be defined as the smallest set sn Tm closed under the rule

\frac{^{}^{}sn}{sn}

In this section, we show that SN sn.

Immediate closure properties of sn. By analyzing the possible reductions of a term depending on its shape, we immediately obtain the following closure properties of sn:

\overline{sn}  \overline{sn}  \frac{sn}{sn}  \frac{sn  ↢  sn}{sn}

Since ( ) is not a value, ( ( )) is never a redex. Thus, the following two closure properties are a consequence of the closure property for application:

\frac{( ) sn  sn}{( ) sn}  \frac{( ) sn  _{1} sn}{fix_{}^{}_{1} ( ) sn}

Similarly, fix_{}^{}is not a redex if + 1. Hence, we can add another closure property:

\frac{sn}{fix_{}^{}sn} + 1

Lemma 3.61 (Closure under subterm) The set of strongly normalizing terms is closed under subterm formation.

1. If :: sn then ^{}:: sn.

2. If :: sn then ^{}:: sn.

3. If :: sn then ^{}:: sn.

In each case, # ^{}# .

Proof. Each by induction on . □

Corollary 3.62 If ( )  then ( )  .

Lemma 3.63 (Closure under splitting) If :: [ ] sn then ^{}:: sn and # ^{}# .

Proof. By induction on . □

Closure under strong head expansion. We define a relation _{sn} ^{}by the same rules as _{SN} ^{}except that we require sn instead of SN in the rule shr- . Our goal is to show that sn is closed under _{sn}-expansion.

Lemma 3.64 (Closure under strong head expansion axioms)

1. If [ ] sn then ( ) sn.

2. If (fix_{}^{}) _{1} sn then fix_{}^{}_{1} sn.

3. If ( (fix_{}^{}) _{1}) sn then (fix_{}^{}_{1}) sn.

Proof. 1. By Lemma 3.63 sn. We perform induction on sn and analyze the possible reducts of ( ) . 2. By induction on _{1} sn. 3. By induction on _{1} ( ) sn. □

Lemma 3.65 (sn closed under strong head expansion)

\frac{_{0} _{sn} _{1} _{1} sn}{_{0} sn}

Proof. By induction on _{0} _{sn} _{1}. In case of shr- , shr-rec , or shr-corec , apply Lemma 3.64. In case ( _{0}) _{sn} ( _{1}), we have _{0} sn by induction hypothesis, since _{1} sn by Cor. 3.62. We proceed by side induction on ( ) _{0} sn. Since ( _{0}) is not a redex, each reduction must be either in ( ) or 0. By side induction hypothesis each reduction of ( _{0}) is in sn. □

For each introduction rule of SN we have established a corresponding closure property of sn. Hence, proving SN sn amounts to a routine induction.

Lemma 3.66 (Inductive SN is sound)

1. If ::  _{SN} ^{}then  _{sn} ^{}.

2. If :: SNe then = ( ) sn for some and .

3. If :: SN then sn.

Proof. Simultaneously by induction on . □

Theorem 3.67 (Strong normalization) If Γ : , then there are no infinite reduction sequences starting with .

Proof. By Cor. 3.50 and the previous lemma, sn. By induction on sn we can prove that ^{}^{}, i. e., reduces to a normal form in finitely many steps. □

84 CHAPTER 3. TYPE-BASED TERMINATION

Embeddings into F_{}

In this chapter, we consider type and reduction preserving embeddings of some total type systems into F_{}. Such embeddings provide a translation function ⌜ ⌝ for terms, types, and possibly kinds of the source language into the target language F_{}. An embedding is type preserving if for all Γ : of the source language, it holds that ⌜Γ⌝ ⌜ ⌝ : ⌜ ⌝ in the target language. Similarly, if a source reduction step ^{}maps to a sequence ⌜ ⌝ ^{+} ⌜ ^{}⌝ of target reduction steps, we speak of a reduction preserving embedding.

For the purpose of embeddings, it is important that F_{}is strongly normalizing. If F_{}was only normalizing w. r. t. a very specific reduction strategy, then the reductions of the source language would not likely map to F_{}reductions that are covered by the strategy. Therefore we have shown strong normalization of F_{}, as opposed to showing just weak normalization.

4.1 An Iso-Recursive Version of F_{}

In our presentation of F_{}, we decided that inductive and coinductive types should be equi-recursive: By the rules ty-fold and ty-unfold , a fixed point is identical to its unfolded version ( ). Alternatively, we can present the system iso-recursively: We drop the rules ty-fold and ty-unfold and introduce two new term constructors:

Tm  ::=  in out

These two terms witness the isomorphism between the fixed point and its unfolded version. Hence, they are typed as follows:

ty-in \frac{Γ : (\overline{}_{}) }{Γ in : \overline{}_{}( + 1) } \overline{}\overline{}\overline{}

ty-out \frac{Γ : \overline{}_{}( + 1) }{Γ out : (\overline{}_{}) } \overline{}\overline{}\overline{}

We overline \overline{}and \overline{}to distinguish them from the inductive and coinductive constructors of the equi-recursive system. The contraction rules for recursive and corecursive functions are replaced by the following ones, and we add a reduction witnessing that (in out) is a retraction pair.

iso-rec  fix_{}^{}_{1}(in ) ↣ (fix_{}^{}) _{1}(in )
iso-corec  out (fix_{}^{}_{1}) ↣ out ( (fix_{}^{}) _{1})
iso- _{}out (in )  ↣

The corresponding reduction relation is confluent in a natural way, in contrast to the equi-recursive system, where we had to introduce restrictions to remove critical pairs (see Remark 3.9).

In previous work [Abe03, Abe04], we have considered such iso-recursive systems. They seem to be easier to handle than their equi-recursive counterparts. The reduction rule iso-rec for recursive functions is more concrete than its counterpart red-rec in F_{}. Here, recursive functions can be unfolded if applied to a data constructor, in this case, in. There, the argument can be any kind of value. Similarly, corecursive functions are only unfolded under a destructor, out, whereas it can be any kind of evaluation context in F_{}. Critical pairs like fix_{0}^{}(fix_{0}^{}^{}) do not arise in the iso-recursive version.

Proofs of strong normalization using saturated sets are considerably simpler for iso-recursive systems than for their equi-recursive counterparts. This is because the semantics of an iso-inductive type is quite concrete: it contains all terms which evaluate to a constructor expression (plus neutral terms). In contrast, the semantics of an equi-inductive type is just its unfolding, we do not get an information on the shape of its inhabitants. We therefore require in our soundness proof in Section 3.5 that all non-neutral terms in a semantical type reduce to a value, which makes strong normalization harder to prove than in the iso-recursive case. To handle equi-coinductive types we even had to refine our notion of saturated set in Section 3.4.3, which is not necessary for iso-coinductive types [AA00, Abe03]. In the following, however, we establish strong normalization of the iso-recursive system effortlessly by embedding it into the equi-recursive one.

Let 1 := : and id := : 1. We define a translation ⌜_⌝, which maps terms of the iso-recursive system to terms of F_{}, constructors to constructors, and typing contexts to typing contexts. It is defined homomorphically for all constructions except the following:

⌜\overline{}_{}⌝ =  _{}( 1  )

where = and =

⌜in ⌝ =  ⌜ ⌝  FV( )
⌜out ⌝ = ⌜ ⌝ id

The translation preserves well-typedness. Consider the derivation:

{⌜ ⌝ : (⌜ _{}⌝ ) \atop ⌜ ⌝ : ( _{}( 1  ))} ; ⌜ ⌝ : 1 ( _{}( 1  )) ; ⌜ ⌝ : _{}( + 1) ( 1  ) ; ⌜in ⌝ : ⌜ _{}⌝ ( + 1)

This derivation can be lifted to _{}for higher kinds , and a similar derivation can be constructed for ⌜out ⌝. Since all other constructions are translated homomorphically, the first part of the following theorem is a routine induction:

Theorem 4.1 (Typing and reduction are simulated)

1. If Γ : in the iso-recursive system, then ⌜Γ⌝ ⌜ ⌝ : ⌜ ⌝ in F_{}.

2. If ^{}in the iso-recursive system, then ⌜ ⌝ ^{+} ⌜ ^{}⌝ in F_{}.

Simulation of reduction is easy as well. We have chosen the translation such that ⌜in ⌝ is a non-recursive value and ⌜out _⌝ is a non-recursive evaluation frame. Hence,

fix_{0}^{}⌜in ⌝  (fix_{0}^{}) ⌜in ⌝  and
⌜out (fix_{0}^{})⌝  ⌜out ( (fix_{0}^{}))⌝

which can be lifted to (co)recursive functions with more arguments. It is also clear that ⌜out (in )⌝ = ( ⌜ ⌝) id ^{+} ⌜ ⌝. It follows that strong normalization of the iso-recursive system is inherited from F_{}.

Remark 4.2 Embedding the equi-recursive into the iso-recursive seems much harder, we need at least to translate the typing derivations. This suggests that the equi-recursive is more foundational than the iso-recursive one and justifies our choice of F_{}.

4.2 Some Systems for Termination

In the following, we discuss the embedding of several systems which can be seen as precursors to F_{}. Here, we concentrate on terminating systems with inductive types, and in the next section we switch to the dual case of productive systems with coinductive types.

The calculus . The closest relative to F_{}is definitively , a calculus introduced by Barthe, Frade, Giménez, Pinto, and Uustalu [BFG^{+} 04] and in depth studied in Frade’s Ph.D. thesis [Fra03]. It is a simply-typed -calculus with sized iso-inductive types and a reduction rule for recursive functions which is similar to iso-rec . It does not have first-class polymorphism (it features MLpolymorphism for types and sizes) nor inductive type constructors. The extension of admissible types we will consider in Chapter 5 is also not present in their system. We claim here that smoothly embeds into F_{}which is strictly more powerful. The only technical work involved to construct an embedding is the translation of ’s Haskell-style inductive types into our equi-recursive types, but this is standard: use product and disjoint sum types.

My calculus Λ_{}^{+} [Abe04]has simple iso-inductive types and their approximations, which are an notational variant of sized types with the disadvantage that they do not integrate well with polymorphism.^{1} Similar problematic formulations have been devised by Amadio and Coupet-Grimal [ACG98], Giménez [Gim98], and Barras [Bar99]. The type syntax of and F_{}, which resembles Hughes, Pareto, and Sabry’s Synchronous Haskell [HPS96, Par00], is a clear improvement: it is both more intuitive and more powerful since it is orthogonal to all other type constructions, like, for instance, polymorphism. Λ_{}^{+} embeds into , and, even more directly, into F_{}.

Some syntactic termination criteria. Giménez proposed a termination criterion on well-typed terms called guarded by destructors. Barthe et al. [BFG^{+} 04] formalized it in the calculus _{}, which embeds into , therefore also into F_{}. In previous work [Abe00] I have described functional language foetus with inductive types and nested recursion, which embeds into Λ_{}^{+} . Note, however, that the termination checker foetus that is described in [AA02] handles also cases of mutual recursion that cannot be expressed by nested recursion, and, thus, not be simulated in F_{}.

4.3 Some Systems For Productivity

Barthe et al. [BFG^{+} 04] sketch an extension of by coinductive types. They do not extend the proofs of subject reduction and strong normalization, but no complications are to be expected there, partly because they work with isocoinductive types. (In the case of equi-coinductive types, the definition of saturated set needs to be refined, see Section 3.4.3.) The extension of by coinduction also embeds into F_{}.

1Λ_{}^{+} uses bounded quantification to model approximations of an inductive type, whereas F_{} uses size polymorphism. Consider the type of the list filter function:

F_{}( Bool)  List^{}List^{} Λ_{}^{+}  ( Bool)  List This worked ok, but the type of the map function ( ) List^{}List^{}cannot be expressed in Λ_{}^{+} .

My calculus ^{fix} [Abe03]is an extension of Λ_{}^{+} [Abe04] by coinductive types and continuity (which will be discussed in Chapter 5). It allows corecursive functions to return pairs, which is not allowed in F_{}. But taking away this slightly buggy feature^{2}, ^{fix} embeds into F_{}.

The guard condition by Amadio and Coupet-Grimal [ACG98]. They present a -calculus with coinductive types and nested corecursion, with a more restrictive syntax than ^{fix} . Besides proving strong normalization with Girard’s reducibility method, they also give a PER model to reason about corecursive programs. The version of their calculus with reduction rules embeds into ^{fix} , therefore also into F_{}.

Syntactic guardedness. Coquand [Coq93] first described a syntactic criterion for productivity: each recursive call must be guarded, i. e., occur under a constructor. This condition is easy to check, but quite restrictive; it rejects advanced corecursion schemes, as, for instance, used for the Huffman decoder in Section 3.2.4. Coquand’s criterion is subsumed by Amadio and Coupet-Grimal’s calculus.

4.4 Iteration and Primitive Recursion

There are a number of calculi without explicit recursion that are normalizing by virtue of typing: the simply-typed -calculus, the polymorphic -calculus (System F) and the higher-order polymorphic -calculus (System F^{}), to name a few examples. In System F, a limited form of recursion, so-called iteration, can be simulated, but not primitive recursion, a strengthening of iteration. This negative result has been proven for the -version of System F by Splawski and Urzyczyn [SU99], for it is conjectured. Primitive recursion can be simulated in the presence of positive fixed-point types [Geu92]. The emphasis is on positive, as opposed to strictly positive. Since F_{}has non-strictly positive least and greatest fixed-point types, this simulation of primitive recursion can be carried out in F_{}, even without the use of fix.

Using fix, primitive recursion is even directly definable, which is not really surprising, considering the flexibility of the typing of fix. For example, the recursor for lists can be programmed as follows:

primRec :  (  ^{}) List^{}
primRec :=  fix_{0}^{}primRec match with
nil
cons as  as(primRecas)

(Better known is the iterator for lists, called foldr in Haskell, which we get from the recursor if we omit the argument as : List^{}to .)

2I later discovered that in ^{fix} there are not enough reductions for corecursive functions [Abe05].

The type we have given to primRec above is its usual System F type. In F_{}, we can give it a more precise type:

primRec :  :ord ^{+}

( ( + 1))

( List^{}( + 1)) List^{}

Mendler-style recursion. Mendler was the first to present formulations of (co)iteration [Men91] and primitive (co)recursion [Men87] that resemble generalized recursion, but are in their power limited through typing. His achievements make him the “father” of type-based termination. The systems discussed in the last two sections are inspired by Mendler and tried to improve on his work. Mendler proved strong normalization of his iteration and recursion constructs by transfinite induction, similarly to how we motivate and verify our recursion rule. The semantic model behind Mendler’s recursion rule

MRec : ( (  ) ( )  )

is very nicely summarized by Splawski and Urzyczyn [SU99]: the variable stands for any approximation ^{}of the inductive type , and = ( ^{}) = ^{+1} for the next approximation. If one defines a function

MRec ( emb rec )

by Mendler recursion, then the function body : constructs a result from argument : ^{+1} where it may invoke recursion rec : ^{}on inductive data of the previous approximation stage. Additionally, it can convert this piece of data into the full inductive type using emb: ^{}^{}(this conversion option is absent in case of Mendler iteration).

Semantically, Mendler already used sized types, but he decided to conceal them using a type variable . This way, he does not extend the type syntax of polymorphic -calculus, which makes his solution quite elegant.^{3} However, subsequent research seems to have been fixed to this type variable representation of approximations ^{}of an inductive type. The resulting type systems by Giménez [Gim98] and myself [Abe03, Abe04] were a bit clumsy. Introduction of sizes into the type system, which was done by Hughes, Pareto, and Sabry [HPS96] in the functional programming community, cleaned up this messy syntax: Barthe et al. [BFG^{+} 04] first realized that these sizes can be interpreted as ordinals, and F_{}features the quite intuitive syntax ^{}.

Mendler uses positive iso-inductive types with the constructor in : ( ) . His recursion scheme is directly definable in the iso-recursive version of F_{}:

MRec = fix_{0}^{}mrec id mrec(out )

3The syntax seems to be a sacred cow in the logic, type theory, and programming language community: Syntax extensions and changes might not be accepted by the fellow researchers. On the other hand, new and better notation is a catalyzer for new ideas, as the history of mathematics shows.

It was later observed by Matthes [Mat98] and Uustalu and Vene [UV99] that Mendler-style inductive types do not have to be positive, since there is no destructor out : ( ). In the absence of a destructor, negative types do not jeopardize normalization since for them the recursion principle MRec is simply useless. The non-positive version of Mendler inductive types cannot be simulated directly, but via the usual encoding into positive fixed-point types [Geu92].

Iteration and primitive recursion for inductive constructors. For (co)inductive constructors of higher kind, Mendler (co)iteration and (co)recursion can be defined analogously. This has been demonstrated in joint work with Matthes and Uustalu [AMU03, AMU05]. The encoding of MRec given above can be lifted to higher kinds and makes crucial use of inductive constructors of higher kind, which are present in F_{}but not in . For non-positive Mendler-style constructors, the recursion schemes can be encoded into positive fixed-point constructors as shown in joint work with Matthes [AM04]. Conventional iteration for inductive constructors [AM03] embeds into Mendler-style iteration [AMU05]; but conventional primitive recursion for higher kinds has not yet been studied.

We have mainly considered the inductive case, but all embeddings dualize to coinduction.

92 CHAPTER 4. EMBEDDINGS INTO F_{}

Continuity

In this chapter, we turn our attention to the question which types are admissible for (co)recursive functions. In sections 3.4.2 and 3.4.4 we have given semantical criteria. The syntactical criteria in Section 3.1 were quite crude approximations, now we try to do better.

As described in the introduction, there are two criteria for admissible (semantical) types : ord .

1. (0) must be the biggest type, the universe of terms,

2. inf_{}( ) ( ).

The first criterion is fulfilled by the general shape of the type: In case of recursion, must be a function type with one domain which is an inductive type, in case of corecursion, it must be an coinductive type or a function type with a coinductive type as codomain. We will not try to relax the first criterion here, some directions of future work are hinted at in Section 7.2. Hughes, Pareto, and Sabry [HPS96] do have a wider criterion, but they only give a denotational semantics and do not have to deal with the extra complications we have by allowing reduction in any order and under binders. Their criterion is not sound in our reduction semantics.

The second criterion looks like a continuity property, if we write it as

inf_{}( ) (sup_{})

However, it talks about infimum and supremum instead of limits and it is an inequation instead of an equation. In previous work [Abe03] we characterized some types that fulfill this condition syntactically. In the following, we generalize this work to polymorphism and type constructors. At the end of this chapter, we will have a syntactical derivation system for admissible types which is much less restrictive than the original one in Section 3.1.

Supremum on [[ ]]. In Section 3.4 we introduced two flavors of saturated sets. The second version defined a saturated set as the orthogonal of a set of evaluation contexts, and we could not establish that the supremum of saturated sets is identical to their union. However, for the development in this chapter, especially the proof of the central lemma 5.8, we require that sup_{}_{}implies _{}for some . It could be that this property holds for saturated sets in the refined sense, but we do not know. However, it holds for saturated sets in the original sense, therefore, we revert to the original definition. The price we have to pay is that coinductive constructors can no longer be treated in “equi” style but we have to switch to “iso” style. The necessary changes to F_{}and its soundness proof are spelled out in Appendix B. In the following, we assume that the supremum on [[ ]]is the set-theoretical union.

5.1 On the Necessity of Criterion 2

In a previous article [Abe04, Sec. 6.1] we proved that the type-based termination system indeed becomes unsound if we drop criterion 2: In the absence of this criterion, one can construct a looping term. In the following, we will convert this example to F_{}:

Assume sized type Nat with the two constructors zero : Nat^{+1} and succ : Nat^{}Nat^{+1} . For simplicity of presentation, we assume that we have a simple pattern-matching facility. We define the following functions:

shift :  (Nat^{}Nat^{+2} ) Nat^{}Nat^{+1}
shift :=  match (succ ) with
zero  zero
succ
plus2 : Nat^{}Nat^{}
plus2 :=  succ (succ )

It is easy to see that plus2 is a fixed point of shift:

shift plus2 : Nat^{}Nat^{} shift plus2 ^{+} plus2

Disregarding Criterion 2, the following function is well-typed:

loop :  Nat^{}(Nat^{}Nat^{+1} ) Nat^{}
loop := fix_{0}^{}loop _match ( zero) with
zero  zero
succ  match with
zero  zero
succ  loop (shift )

To see well-typedness, here some help with the types of the bound variables and some subterms:

loop : Nat^{}(Nat^{}Nat^{+1} ) Nat^{}
_: Nat^{+1}
: Nat^{}Nat^{+2}
: Nat^{+1}
: Nat^{}
shift : Nat^{}Nat^{+1}

Now a certain function call loops:

loop zero plus2 ^{+} loop zero (shift plus2) ^{+} loop zero plus2

It is also not the case that the occurrence of + 1 in the type of loop is causing the non-termination. We can modify the counterexample such that the +1 disappears from the type of loop. To this end, introduce a free variable err : . If we modify the definition of shift such that in the case zero the variable err is returned, then shift can be given type (Nat^{}Nat^{+1} ) Nat^{}Nat^{}. If we remove one pattern matching layer from loop it gets type Nat^{}(Nat^{}Nat^{}) Nat^{}, and loop zero ( succ ) loops. Thus, it is really the negative occurrence of the type Nat^{}Nat^{[+1]} that enables a looping term.

5.2 Semi-Continuity

When we define a (co-)recursive object of type : ord ( ), we prove in the semantics that ( ) for all ordinals ^{ord} by transfinite induction on . In the case of a limit ordinal , we have _{}( ) = inf_{}( ) and need to show ( ). Hence, must be a function over ordinals with the property

inf_{}( )  (5.1)

We are looking for a syntactical characterization of types that fulfill (5.1). For instance, what is required of and such that = has this property? We would expect that has to fulfill (5.1) and some dual property. However, it is not that simple: To show inf_{}( ( ) ( )) ( ) ( ) from inf_{}( ) requires that ( ) inf_{}, which is not even fulfilled if ( ) denotes the natural numbers below . This means that not even for type Nat^{}Nat^{}we can show property (5.1) directly.

The next idea is to strengthen the requirement to lim_{}( ) which by Lemma 3.14 entails (5.1). Here we hit the problem that many function spaces do not have limits. For example, let ( ) = at( ) at( ) denote the family of endo-functions on natural numbers below . Consider the function which increases even numbers by one, but leaves odd numbers unchanged. This function inhabits ( ) for infinitely many (namely every second

), hence  lim sup _{}. But there is no _{0}  such that  ( ) for all

between _{0} and , hence, lim inf _{}. Since limes superior and inferior differ, lim_{}does not exist.

Although limits might not exist, it has been observed by Hughes, Pareto and Sabry [HPS96] and the author [Abe03] that the modified requirement

lim inf_{}( )  (5.2)

can be lifted over function types:

Proposition 5.1 Let O be some initial segment of the ordinal numbers, O a limit ordinal, and O SAT. If ( ) lim inf _{}and lim inf _{}( ) then lim inf _{}( ( ) ( )) ( ) ( ).

This proposition is true, and the condition on , ( ) lim inf _{}, is exactly what we need. The condition on is sufficient, but rather ad hoc, and we will replace it by the stronger requirement

lim sup_{}( )  (5.3)

which is the dual to the requirement on . The nature of his choice is not technical but aesthetical: symmetry. Further, now the requirements on and correspond to already-known mathematical concepts:

Semi-continuity. Let (𝔏 inf sup) be a complete lattice, O some initial segment of the ordinal numbers and O a limit ordinal. A function O 𝔏 is called upper semi-continuous in if

lim sup_{}( )  (5.4)

It is called lower semi-continuous in if

( ) lim inf_{}(5.5)

The function is upper/lower semi-continuous, if it is so in all limit ordinals O. A function is called -overshooting by Hughes, Pareto, and Sabry [HPS96], if it is lower semi-continuous in .

The term semi-continuity is justified by the following observation:

Lemma 5.2 If is both upper and lower semi-continuous in , then it is continuous in .

Proof. By assumption, lim sup _{}( ) lim inf _{}. By Lemma 3.14, the limes inferior is below the limes superior, hence both are equal and the limit lim_{}exists. Since ( ) is sandwiched between the limit on both sides, it is equal to the limit. Thus, is continuous in . □

Remark 5.3 (Undershooting + overshooting = continuous) Property (5.2), lim inf _{}( ), which we have called paracontinuous in previous work [Abe03], and which would be called -undershooting following Hughes, Pareto, and Sabry [HPS96], is not strong enough to complement lower semi-continuity. For instance, consider the function O 𝔏 which maps all odd finite ordinals to and all others to . It is both -under- and -overshooting, since lim inf _{}= ( ) = , but not continuous in , since lim sup _{}= .

Set of semi-continuous functions. We denote the set of upper semi-continuous functions from O to 𝔏 by O ^{}𝔏, and the set of lower semi-continuous functions by O ^{}𝔏.

Lemma 5.4 (Variance and semi-continuity) (O ^{+} 𝔏) (O ^{}𝔏) and (O ^{}

𝔏) (O ^{}𝔏).

Example 5.5 (Ordinal successor) The ordinal successor is upper semi-continuous, since it is monotone, but not lower semi-continuous.

The concepts (5.4) and (5.5) are clearly subconcepts of continuity. Familiar subconcepts are continuity from the left/right, but since we are considering functions over ordinals, every function is continuous from the right.^{1} But we could ask the following question: what makes a monotone function on ordinals continuous (from the left)? We find:

1. An antitone function is already continuous if it is upper semi-continuous.

2. An isotone function is already continuous if it is lower semi-continuous.

So we could say that an upper semi-continuous function is continuous when falling and a lower semi-continuous function is continuous when climbing.

5.3 Type Constructors and Semi-Continuity

In the following, we will analyze which type constructors preserve upper and lower semi-continuity. For the first kind, we need to push an upper limit under the type constructor, for the second kind, we need to pull a limit out from the argument of a type constructor.

Preservation of upper semi-continuity. We say lim sup pushes through 𝔏 𝔏^{}if for all O 𝔏 and all O it holds that

lim sup_{}( ( )) (lim sup_{}( ))

1Minima always exists on the ordinals, hence, limits of falling sequences are all trivial, and since the ordinals are wellfounded, there are no infinite strictly falling sequences.

We also say that is a lim sup -pushable function.

Most of our type constructors are covariant. This allows the following reasoning: If 𝔏 ^{+} 𝔏^{}is lim sup -pushable and O 𝔏 is upper semicontinuous, then

lim sup_{}( ( )) (lim sup_{}( )) ( ( ))

hence, preserves upper semi-continuity.

Remark 5.6 (Covariance alone not sufficient) In general, covariance is not sufficient to preserve upper semi-continuity. Consider the function : [0 1] [0 1] on the real or rational unit interval with ( ) = 1 . Then clearly is (left) upper semi-continuous at 1, since is even continuous. However, taking to be the sign function such that ( ) = 1 if 0 and (0) = 0, we have lim sup _{1} ( ( )) = 1, but ( (1)) = 0.

Preservation of lower semi-continuity. We say lim inf can be pulled through 𝔏 𝔏^{}if for all O 𝔏 and all O it holds that

(lim inf_{}( )) lim inf_{}( ( ))

We also say that is a lim inf -pullable function.

If 𝔏 ^{+} 𝔏^{}is lim inf -pullable and O 𝔏 is lower semi-continuous, then

( ( )) (lim inf_{}( )) lim inf_{}( ( ))

thus, preserves lower semi-continuity.

Contravariant constructors. If is contravariant and a lim sup can be pushed into , becoming a lim inf , then turns lower semi-continuous functions into upper semi-continuous ones. If a lim sup can be pulled out from as a lim inf , then maps a upper semi-continuous function to an lower semi-continuous one.

Lemma 5.7 Let O O 𝔏 and O proper limit. Then

lim sup_{}( )  lim sup_{}lim sup_{}( )
lim inf_{}lim inf_{}( )  lim inf_{}( )

Proof. Let all ordinals range below .

sup_{_{0}} ( ) sup_{_{0}} sup_{_{0}} ( )  for all _{0}
= inf_{_{0} _{0}} inf_{_{0} _{0}} sup_{_{0}} sup_{_{0}} ( )
inf_{_{0}} sup_{_{0}} ( ) inf_{_{0}} inf_{_{0} _{0}} inf_{_{0} _{0}} sup_{_{0}} sup_{_{0}} ( )  taking inf on both sides
= inf_{_{0}} inf_{_{0}} sup_{_{0}} sup_{_{0}} ( )
= inf_{_{0}} sup_{_{0}} inf_{_{0}} sup_{_{0}} ( )

This means that lim sup _{}( ) lim sup _{}lim sup _{}( ). The second claim follows by dualization. □

5.3.1 Function Space

In this section, we show that function spaces can be upper semi-continuous, but not lower semi-continuous.^{2}

Lemma 5.8 (Pushing lim sup through function space) Let O (Tm) and O a limit ordinal. Then

lim sup_{}( ( ) ( )) (lim inf_{}) lim sup_{}

Proof. We assume a function term lim sup _{}( ( ) ( )) and an argument term sup_{_{0}} inf_{_{0}} ( ) and show that the application inf_{_{0}} sup_{_{0}} ( ). In the following, let all ordinals range below . We fix an arbitrary ordinal _{0}. We know that there exists some _{0} such that

( ) for all  _{0}. Furthermore,  ( ) ( ) for some ordinal
max( _{0} _{0}). Since  ( ), we conclude  ( ).  □

Corollary 5.9 Let O ^{}(Tm), O ^{}(Tm) and ( ) := ( ) ( ). Then O ^{}(Tm).

Proof. Fix some limit ordinal O. Since ( ) lim inf _{}and lim sup _{} ( ), the desired inequation

lim sup_{}( ( ) ( )) ( ) ( ) follows from the previous lemma, since the function space is contravariant on the domain and covariant on the codomain. □

2An exception could be functions over finite domains, which are lower semi-continuous in their codomain. But we do not distinguish between finite and infinite here, this would require a syntactical calculus of finiteness later.

The converse lemma to derive that ( ) ( ) is lower semi-continuous does not hold. For instance ( ) := at^{}at^{}is not lower semi-continuous, although at^{}is: the identity function is in ( ), but not in ( ) for any .

Remark 5.10 (Cannot pull lim inf out of function space) We show that not generally (lim sup _{}( )) lim inf _{}( ( ) ). Clearly, the bigger (lim inf _{}( )) is then also not below lim inf _{}( ( ) ) in general. Take ( ) = at^{}atand = at. First, we show

( 0) (lim sup_{}( at^{}at)) at

We assume that for all _{0} there is some  _{0} such that  at^{}atand

show ( 0) at. Since 0 at^{1} we have at^{}atfor some 1 and therefore 0 at. Since at = _{_{0}} at^{_{0}} , there must be a _{0} such that 0 at^{_{0}} . Thus, ( 0) atfor some _{0}. Now, we prove

( 0) lim inf_{}(( at^{}at) at)

We show even that ( 0) is in none of the sets ( at^{}at) at. Assume an arbitrary . Let be the function which returns for inputs less than and diverges for all input greater or equal than . Then at^{} at. But since 0 evaluates to , ( 0) diverges and, hence, cannot be in at.

5.3.2 Universal Quantification

Universal quantification is semantically interpreted by intersection. We can only show that quantification preserves upper semi-continuity.

Lemma 5.11 (Pushing lim sup through infimum) Let some index set, O 𝔏, and O some limit ordinal. Then

lim sup_{}inf_{}( ) inf_{}lim sup_{}( )

Proof. For all it holds that inf_{}( ) ( ). Since inequation is preserved under limit formation, lim sup _{}inf_{}( ) lim sup _{}( )

for all  , which entails our claim.  □

Corollary 5.12 The space of upper semi-continuous functions O ^{}𝔏 forms a complete lattice under pointwise ordering, pointwise infimum, and pointwise maximal element.

Proof. To see that O ^{}𝔏 is closed under pointwise infimum, assume a family O 𝔏 (for ) with lim sup _{}_{}( ) _{}( ) for all . Minimizing both sides, we obtain

lim sup_{}(inf_{}_{})( ) inf_{}(lim sup_{}_{}( )) (inf_{}_{})( )

by pulling the upper limit out to the left (previous lemma). □

Example 5.13 (Supremum on O ^{}𝔏 not pointwise) The supremum of the lattice, sup_{}_{}= inf _{}for all , however, is not the pointwise one. For example, take the two element lattice and the family

: [0; ]  for 0
( ) :=  if
( ) :=  else.
Then _{}( ) =  _{}( ) for all  , hence each _{}is upper semi-continuous

in . However, the pointwise supremum ( ) := sup_{}_{}( ) takes the value below , hence lim sup _{}= ( ) = .

On the contrary, lower semi-continuous functions are not closed under pointwise infimum. This becomes clear if we consider the same example on the dual lattice, i. e., we swap inf and sup, and and (which means that becomes the maximal element and the minimal). With the same trick, we harvest a relationship between supremum and limes inferior:

Lemma 5.14 (Pulling lim inf out of a supremum) Let some index set, O 𝔏, and O some limit ordinal. Then

sup_{}lim inf_{}( ) lim inf_{}sup_{}( )

We could now turn O ^{}𝔏 into a complete lattice using the pointwise supremum. But we withstand this temptation since this would trick us into believing we could interpret universal quantification on this lattice.

Remark 5.15 One would think that, if ^{}is lower semi-continuous, then also . But it is not true in our semantics. It is not clear whether it holds in another semantics, e. g., one with parametricity.

5.3.3 Coinductive Types

Clearly, coinductive types are not lower semi-continuous in general. For example, consider the stream of subsequent natural numbers 0 1 which is an element of Stream^{}(Nat^{}). Since for all , this stream is not contained in Stream^{}(Nat^{}), the latter type family cannot be lower semi-continuous in .

However, coinductive types map upper semi-continuous types to upper semi-continuous types under some conditions. We introduce a new symbol for antitone iteration, which is used to construct the semantics of coinductive types:

\begin{matrix} & & O ^{}(𝔏 ^{+} 𝔏) ^{+} 𝔏 \\ ^{}( ) & = & ^{}( ) \end{matrix}

By Lemma 3.21, is antitone in its first argument, hence by Lemma 3.17 we can replace the limit by an infimum at limit iterates: ^{}= inf_{}^{}. This will enable us to reason about semi-continuity.

Lemma 5.16 Let O O and O. Then

1. sup_{}^{( )} ^{inf_{}},

2. sup_{}^{( )} ^{inf_{}},

3. inf_{}^{( )} ^{sup_{}}, and

4. inf_{}^{( )} ^{sup_{}}.

Proof. 1. and 3. follow directly from antitonicity. For 2., remember that each set of ordinals is left-closed, hence inf_{}= ( ) for some . The remaining proposition 4. is proven by cases on sup_{}. If sup_{}is not a limit ordinal then sup_{}= ( ) for some . For this , clearly ^{( )} ^{sup_{}}, which entails the lemma. Otherwise, if sup_{}is a limit ordinal, then by definition of at limits we have to show inf_{}^{( )} ^{}for all sup_{}. By definition of the supremum, ( ) for some . Since is antitone, ^{( )} ^{}from which we infer our subgoal by forming the infimum on the left hand side. □

Hence, we can push a supremum as an infimum under antitone iteration, and vice versa.

Corollary 5.17 lim sup _{}^{( )} = ^{lim inf _{}( )} .

Lemma 5.18 (Coinductive types are lim sup -pushable) Let ( _{})_{O} be a family of lim sup -pushable isotone endo-functions on a complete lattice 𝔏 with pointwise infimum and supremum. Then

lim sup_{}^{}_{}^{}lim sup_{}_{} Proof. By induction on . In case = 0, both sides become the maximum element of 𝔏. In the successor case we have

lim sup _{}^{+1} _{}= lim sup _{}_{}( ^{}_{})
lim sup _{}lim sup _{}_{}( ^{}_{})  Lemma 5.7
lim sup _{}_{}(lim sup _{}^{}_{})  _{}pushable
lim sup _{}_{}( ^{}(lim sup _{}_{}))  _{}isotone, i.h.
= (lim sup _{}_{})( ^{}(lim sup _{}_{})) inf, sup pointwise
= ^{+1} (lim sup _{}_{})

Note that in the last step we used that lim sup is defined pointwise on functions. In the remaining case = we exploit that lim sup pushes through infima (Lemma 5.11). □

Corollary 5.19 Under the assumptions of the last lemma.

lim sup_{}^{( )} _{}^{lim inf _{}}lim sup_{}_{}

Proof. We combine Cor. 5.17 and Lemma 5.18.

lim sup _{}^{( )} _{}lim sup _{}lim sup _{}^{( )} _{}Lemma 5.7
lim sup _{}^{( )} (lim sup _{}_{}) Lemma 5.18
lim inf _{}( ) lim sup _{}_{}Cor. 5.17 □

Corollary 5.20 (Coinductive types preserve upper semi-continuity) For O, let _{}𝔏 ^{+} 𝔏 be lim sup -pushable. The family _{}be upper semi-continuous. Then

lim sup_{}^{( )} _{}^{lim inf _{}}_{}

Proof. By the last corollary and upper semi-continuity of _{}. □

5.3.4 Inductive Types

The result of the last section can be dualized to inductive types. We define isotone iteration, ^{}= ^{}( ).

Lemma 5.21 Let  O O and  O. Then ^{sup_{}}= sup_{}^{( )} and

inf_{}= inf_{}^{( )} .

Corollary 5.22 ^{lim inf _{}}= lim inf _{}^{( )} .

Lemma 5.23 (Inductive types are lim inf -pullable) For O, let _{}𝔏 ^{+} 𝔏 be lim inf -pullable. Then isotone iteration ^{}_{}is lim inf -pullable, i. e.,

lim inf_{}_{}lim inf_{}^{}_{}

Corollary 5.24 Let be a lower semi-continuous function on ordinals. In the context of the lemma,

( ) lim inf_{}_{}lim inf_{}^{( )} _{}

Corollary 5.25 (Inductive types preserve lower semi-continuity) Under the assumptions of the last corollary isotone iteration ^{( )} _{}is lower semi-continuous, i. e.,

( ) _{}lim inf_{}^{( )} _{}

if the family _{}is lower semi-continuous.

Since isotone types are upper semi-continuous, many inductive types are trivially upper semi-continuous. First, every type ^{}where does not depend on , but also, for example ist^{}( at^{}) and ree^{}( at at^{}).

But there are other types which are upper semi-continuous as well, for instance ist^{}( tream^{}( at)). This type is acceptable since it’s generator _{}( ) = nit + tream^{}( at) is infimum continuous^{3}, which means that

( ) _{}( ) nit + ( tream^{}( at) tream^{}( at)) ( )

Pareto calls such generators lenient [Par00, p. 122], recasting the conditions as ( ) _{}( ) _{}( ). Since Pareto’s type generators are infimum continuous by definition ([HPS96, Restriction 3.2]), they are also lenient, hence, each inductive type is upper semi-continuous.

On the contrary, our type iterators are not lenient. This is because we allow function spaces in data types. Consider _{}( ) = at^{}which constructs at^{}-hungry functions. Then the identity function is in _{+1} ( at^{+1} ) and in ( at^{}), but not in _{+1} ( at^{+1} at^{}) = at^{+1} at^{}.

If all inductive types would preserve upper semi-continuity, we would have the chain

lim sup_{}^{}_{}^{}lim sup_{}_{}^{}_{}(5.6)

for a isotone, upper semi-continuous type constructor which is lim sup -pushable. In the following, we will construct a counterexample to our hypothesis.

3A function is infimum continuous if inf_{}( _{}) = (inf_{}_{}) for all sequences ( _{})_{}.

An infimum continuous function is isotone. An isotone function is infimum continuous if inf_{}( _{}) (inf_{}_{}). This last condition is what I called “continuous” in earlier work [Abe03].

An inductive type which is not upper semi-continuous. A minor variant of the last example, _{}( ) = 1 + ( at^{}) constructs the family of trees which have at least “good” branches at each node. First, we observe that, using upper semi-continuity of sums and function space,

lim sup _{}_{}( _{})  1 + (lim sup _{}( at^{}_{}))
1 + ((lim inf _{}at^{}) (lim sup _{}_{}))
= 1 + ( at^{}(lim sup _{}_{}))
= _{}(lim sup _{}_{})

Hence, the functor family is lim sup -pushable, but, as we will show, isotone iteration of is upper semi-continuous.

The th iteration ^{}_{}contains the -branching trees of finite height. Let be a -branching tree of height for all . Consider the tree ( ) = _{}, whose root has infinitely many branches, containing the _{}in order. The first 0 branches are good and of height 0 (empty quantification), the first 1 branches are good and of height 1, the first 2 branches are good and of height 2 etc. This implies that

inf_{}sup_{}^{}_{}= lim sup_{}^{}_{}(5.7)

But it is not true that is an infinitely branching tree of finite height, i. e.,

sup_{}^{}_{}= ^{}_{}(5.8)

This invalidates the inequation 5 6 for ordinal = ; inductive types do not generally preserve upper semi-continuity.

Could we nevertheless accept all inductive types as result types of recursive functions without jeopardizing termination? After all, our semantics might be defective, ruling out a class of functions for internal reasons? The answer is no. In the following, we show how to construct a looping term if the inductive type of Nat-hungry functions Hungry^{}(Nat^{}) = ^{}Nat^{}is accepted as result of a recursive function.

Constructing a looping term. We assume that the natural numbers are constructed by the two closed normal forms zero and succ and that there is a elimination case_{Nat}. We postulate the following typings and reductions.

zero  :  Nat^{+1}
succ  :  Nat^{}Nat^{+1}
case_{Nat} :  (Nat^{}) Nat^{+1}
case_{Nat} zero  ^{+}
case_{Nat} (succ ) ^{+}

Since zero and succ are closed and normal, they must be weak-head values, hence, trigger unfolding of recursive functions. We can define a predecessor function on positive numbers as follows:

err :
pred :  Nat^{+1} Nat^{}
pred := case_{Nat} errid

Herein, we had to assume a variable err which inhabits every type. Note that there cannot be a closed term pred of type Nat^{+1} Nat^{}, since then pred zero would be a closed normal form in the type Nat^{}whose semantics at^{0} contains only neutral, i. e., open normal forms. The assumption of variable err is unproblematic, since we are refuting strong normalization in this example, and strong normalization treats also reduction of open terms. It is clear that pred (succ ) ^{+} , hence by induction on , also

pred^{}(succ^{}) ^{+}

for any term .

Next, we define a function which transforms a Nat^{}-hungry function into a Nat^{+1} -hungry function. In the visualization of -hungry functions as - branching trees, this means that we insert a left-most branch at each node.

s :  Hungry^{}(Nat^{}) Hungry^{}(Nat^{+1} )
s := fix_{0}^{}pred
s^{}^{+} s^{}pred^{}

At this, point we can construct a hungry function h recursively, if we disregard that Hungry^{}(Nat^{}) does not denote a upper semi-continuous function. Since the type of hungry functions does not contain values semantically, this is clearly pathological already. Later we will exploit h to construct a non-normalizing term.

h :  Nat^{}Hungry^{}(Nat^{})
h := fix_{0}^{}_s  pred
h ^{+} s h pred

To implement a diverging term, we need the inverse p of s. Intuitively, it cuts the left-most branch of each node.

p :  Hungry^{}(Nat^{+1} ) Hungry^{}(Nat^{})
p := fix_{0}^{}succ
p^{}^{+} p^{}succ^{}

Finally, we define a “traversal” function tr which diverges on h .

tr : Hungry^{}(Nat^{}) 0
tr := fix_{0}^{}tr tr((  succ) zero)
tr  ^{+} tr ((p  succ) zero)

Now, we construct the following reduction sequence for any ℕ.

tr (p^{}(s^{}(h zero)))  ^{+} tr (p^{}(s^{}(s h pred)))
tr (p^{}(s^{+1} h pred^{+1} ))
tr (p^{}s^{+1} h pred^{+1} succ^{})
+ tr ((p^{+1} s^{+1} h pred^{+1} succ^{+1} ) zero)
+ tr (p^{+1} (s^{+1} (h zero)))

It is clear that tr (h zero) diverges.

5.3.5 Product and Sum Types

Product and sum type are both upper and lower semi-continuous. This has been shown by Pareto [Par00] for a denotational semantics, and by myself [Abe03] for a SN semantics for a type system with iso-(co)inductive types. However, I do not know whether this can be shown for the impredicative encodings of sum and product from Example 3.3. In the following, we assume we have the continuity property for sum and product. This might require to add them as primitive notions to F_{}.

Lemma 5.26 Let O (Tm). Then for all limit ordinals O,

( ) lim sup _{}( ( ) ( ))  (lim sup _{}) (lim sup _{})
( ) lim sup _{}( ( ) + ( ))  (lim sup _{}) + (lim sup _{})
( ) (lim inf _{}) (lim inf _{})  lim inf _{}( ( ) ( )) and
( ) (lim inf _{}) + (lim inf _{})  lim inf _{}( ( ) + ( ))

Corollary 5.27 (Product and sum preserve semi-continuity) Let and O ^{}(Tm). Then ( ( ) + ( )) ( ( ) ( )) O ^{} (Tm).

5.4 A Kinding System for Semi-Continuity

In this section we define a calculus to derive semi-continuous constructors. This calculus will be part of the new criterion for admissible types for (co)recursion.

Polarities for semi-continuous functions. Similar to the polarities + , , and for co-, contra-, and non-variant constructors we introduce two new polarities for semi-continuous constructors:

HPol  ::=  upper semi-continuity
lower semi-continuity

Positive contexts. We define contexts Π Cxt^{+} PCxt in which each variable has positive polarity and each kind is pure:

Cxt^{+} Π ::=  empty context
Π :+ _{}positive constructor variable

Well-formed size expressions. The judgement Δ ord singles out wellformed -free constructors of kind ord. With this separate judgement, it is very easy to show that every well-formed is either an affine function in one size variable, or equal to ^{ord}.

ord- \overline{Δ ord}  ord-var \frac{( : ord) Δ  +}{Δ ord}  ord-s \frac{Δ ord}{Δ s ord}

Derivation system for kinds and semi-continuity. Let Δ be a polarized context with ( : ord) Δ for some . We define the judgement Δ; :+ { \atop _{}}^{}: inductively by the following rules. Variables can only appear strictly positive in , and they are disjoint from the variables in Δ. The intended semantics of the judgement depends on : If = then is a well-kinded, upper semicontinuous constructor in ordinal variable , and a lim sup can be pushed into its arguments . If = then is lower semi-continuous and a lim inf can be pulled out from its arguments .

The first three rules enable us to derive semi-continuity from an ordinary kinding judgement Δ : .

cont-in \frac{Δ  :}{Δ : ord; Π ^{}:}

cont-co \frac{Δ :+ ord  :  +}{Δ : ord; Π ^{}:}

cont-contra  \frac{Δ : ord  :}{Δ : ord; Π ^{}:}

These rules are justified by the fact that each invariant function is continuous, each covariant function is upper semi-continuous and each contravariant function is lower semi-continuous. The next rules are for the pure -calculus part of the constructor grammar.

cont-var \frac{:  Δ Π  +}{Δ; Π ^{}:}

cont-abs \frac{Δ : ; Π ^{}: ^{}}{Δ; Π ^{}: ^{}}=

cont-app Δ : ^{}ord; Π ^{}: ^{}^{1} Δ : Δ : ^{}ord; Π ^{}: ^{} Note that in the application rule, we require the argument to be constant in . The background is that the composition of and has trivially all the continuity and variance properties of if is constant. Of course, with this rule we could never derive, e. g., that is upper semi-continuous in if is upper semi-continuous and is lower semi-continuous. Hence, we need specialized rules for the constants, which implement the observations from the last section.

cont-sum \frac{Δ; Π ^{}:}{Δ; Π ^{}+ :}  cont-prod \frac{Δ; Π ^{}:}{Δ; Π ^{}:}

cont-arr \frac{Δ; ^{}:  Δ; Π ^{}:}{Δ; Π ^{}:}

cont- \frac{Δ; Π ^{}:}{Δ; Π ^{}_{}:}

cont-mu \frac{Δ; Π :+ _{}^{}: _{}Δ ^{}: ord}{Δ; Π ^{}^{}: _{}}

cont-nu \frac{Δ; Π :+ _{}^{}: _{}Δ ord}{Δ; Π ^{}^{}: _{}}

We abbreviate Δ; ^{}: by Δ ^{}: .

Example 5.28 (Type of minimum function) Recall that Nat^{}= ^{}1+ . First, we derive that Nat is lower semi-continuous:

\overline{cont-var}

: ord; :+ ^{}:

\overline{cont-sum}

: ord; :+ ^{}1 + :

\overline{cont-var}

: ord ^{}: ord

\overline{cont-mu}

: ord; ^{}Nat^{}:

Since Nat : ord ^{+} is also upper semi-continuous, we can derive that the type of the minimum and maximum functions is upper semi-continuous. We omit : and empty positive contexts Π in the derivation:

: ord ^{}Nat^{}: ord ^{}Nat^{}:+ ord Nat^{} \overline{cont-co} : ord ^{}Nat^{} \overline{cont-arr} : ord ^{}Nat^{}Nat^{}
\overline{cont-arr}

: ord ^{}Nat^{}Nat^{}Nat^{}

Example 5.29 (Stream of natural numbers) Let Stream^{}= ^{}, as defined in Example 2.9. The type Stream^{}Nat^{}is upper semi-continuous.

:+ ord Nat^{}

\overline{cont-co}

: ord; :+ ^{}Nat^{}

\overline{cont-var}

: ord; :+ ^{}

\overline{cont-prod}

: ord; :+ ^{}Nat^{}

\overline{cont-nu}

: ord ^{}Stream^{}Nat^{}

Example 5.30 (Finitely branching trees) Node-labeled forests of height with less than branches can be implemented as ^{}List^{}( ). If we let the two indices coincide, we obtain ^{}List^{}( ), which is upper semi-continuous (since isotone), but also lower semi-continuous. This is an example with two strictly positive variables:

\overline{cont-var} ; :+ ^{}

\overline{cont-prod}

:+ ^{}( )

\overline{cont-var} :+ ^{}
\overline{cont-prod}

:+ ^{}( )

\overline{cont-sum}

:+ ord; :+ ^{}1 + ( )

\overline{cont-mu}

:+ ord; :+ ^{}List^{}( )

\overline{cont-mu}

:+ ord; ^{}^{}List^{}( )

Lemma 5.31 (Soundness of judgement for size expressions) If :: Δ ord then Δ : ord.

Proof. By induction on . □

Theorem 5.32 (Erasure of continuity) If :: Δ; Π ^{}: then Δ Π : .

Proof. By induction on . □

A consequence of the erasure theorem is that all derivations of semi-continuous constructors produce only well-kinded constructors.

5.5 Semantical Soundness of Continuity Derivations

In the following, we will show that all types that are kindable by the calculus of the last section indeed have the postulated semi-continuity properties. We will make use of all the semantical propositions proven in Section 5.3.

Lemma 5.33 If :: Δ ord, then for all [[Δ]]and ordinal variables ,

:= ( [[ ]]_{[ ]}) [[ord]] [[ord]]

is either the constant function ( ) = ^{ord} or a function of the shape ( ) = min + ^{ord} for some natural number .

Proof. By induction on . □

Theorem 5.34 (Semantical soundness) Let [[Δ Π]], ( : + ^{}) Π, [[ord]] [[ ^{}]], and [[ord]]a limit ordinal.

1. If :: Δ; Π ^{}: then

(a) lim sup _{}[[ ]]_{[ ]} ^{}[[ ]]_{[ ]}, and

(b) lim sup _{}[[ ]]_{[ ( )]} ^{}[[ ]]_{[ lim sup _{}]} .

2. If :: Δ; Π ^{}: then

(a) [[ ]]_{[ ]} ^{}lim inf _{}[[ ]]_{[ ]}, and

(b) [[ ]]_{[ lim inf _{}]} ^{}lim inf _{}[[ ]]_{[ ( )]} .

Proof. By induction on .

Case cont-in . A constant function is trivially continuous.

Case cont-co . Isotone functions are upper semi-continuous (Lemma 5.4).

Case cont-contra . Analogously.

Case cont-var . By assumption.

Case cont-abs .

\frac{Δ : ; Π ^{}: ^{}}{Δ; Π ^{}: ^{}}=

For subcase = , we need to show that (a),

lim sup_{}([[ ]]_{[ ]}) ^{^{}}[[ ]]_{[ ]}

It is sufficient that for all [[ ]],

(lim sup _{}[[ ]]_{[ ]})  =  lim sup _{}([[ ]]_{[ ]} )
=  lim sup _{}([[ ]]_{[ ][ ]} )
=  lim sup _{}([[ ]]_{[ ][ ]} )
[[ ]]_{[ ][ ]}
=  [[ ]]_{[ ]}

which follows by induction hypothesis. Goal (b) follows similarly, and case = analogously. We have used that infimum and supremum are defined pointwise on lattices [[ ]], if is an ordinary polarized kind without continuity restrictions (Lemma 2.16).^{4} 112 CHAPTER 5. CONTINUITY

4On lattices with continuity, e. g., O ^{}𝔏, the supremum might not be the pointwise one (Example 5.13!).

Case cont-app . Similarly, by pointwise infimum and supremum. Case cont-sum and cont-prod . By Cor. 5.27. Case cont-arr . By Cor. 5.9. Case cont- . By Cor. 5.12. Case cont-mu .

\frac{Δ; Π :+ _{}^{}: _{}Δ ^{}: ord}{Δ; Π ^{}^{}: _{}}

By induction hypothesis, := [[ ]]_{[ ]} is a lower semi-continuous function on ordinals. Let _{}( ) = [[ ]]_{[ ][ ]} . By induction hypothesis we have for all limits [[ord]], [[ _{}]], [[ord]], [[ord]] [[ _{}]]that

(a) [[ ]]_{[ ][ ]} = _{}( ) lim inf _{}_{}( )
(b) [[ ]]_{[ lim inf _{}][ ]} = _{}(lim inf _{}) lim inf _{}_{}( ( ))

thus, is both lower semi-continuous and lim inf -pullable. Goal (a),

( ) _{}lim inf_{}^{( )} _{}

follows by Cor 5.25. To show (b) for some variable ( :+ ^{}) Π, let = [[ ]]_{}and ( )( ) = [[ ]]_{[ ][ ]} . Then [[ ^{}]]_{[ ]} = ^{}( ). By induction hypothesis (b), for all ^{}[[ ^{}]], [[ _{}]], ord [[ ^{}]], and limit

(b.1) ( ^{})(lim inf _{})  lim inf _{}( ^{})( ( )) and
(b.2) (lim inf _{})  lim inf _{}( ( ))

Since by (b.1) _{}= ( ( )) is lim inf -pullable, we can apply Lemma 5.23, we have for all ,

lim inf_{}( ( )) lim inf_{}^{}( ( ))

Combining this with (b.2), we can prove our goal (lim inf_{}) lim inf_{}^{}( ( ))

Case cont-nu .

\frac{Δ; Π :+ _{}^{}: _{}Δ ord}{Δ; Π ^{}^{}: _{}}

Let _{}( ) = [[ ]]_{[ ][ ]} . By induction hypothesis we have for all limits [[ord]], [[ _{}]], [[ord]], [[ord]] [[ _{}]]that

(a) lim sup _{}_{}( ) _{}( ) = [[ ]]_{[ ][ ]}
(b) lim sup _{}_{}( ( ))  _{}(lim sup _{}) = [[ ]]_{[ lim sup _{}][ ]}

thus, is both upper semi-continuous and lim sup -pushable. First, we observe that the greatest fixed point of _{}is already reached at iterate , because

= lim sup _{}_{}^{}
= lim sup _{}_{}( _{}^{})
(lim sup _{}_{}^{})
= _{}( ^{}_{})
= ^{+1} _{}

(It is well-known that strictly positive coinductive types close at .) By Cor. 5.20, we have

lim sup_{}^{( )} _{}^{lim inf _{}}_{}

Now, by Lemma 5.33, := [[ ]]_{[ ]} is either affine or constantly ord. In both cases, ( ) and lim inf _{}, hence, goal (a),

lim sup_{}^{( )} _{}^{( )} _{}

follows since the fixed-point is reached at .

To show (b) for some variable ( :+ ^{}) Π, let = [[ ]]_{}and ( )( ) = [[ ]]_{[ ][ ]} . Then [[ ^{}]]_{[ ]} = ^{}( ). By induction hypothesis (b), for all ^{}[[ ^{}]], [[ _{}]], ord [[ ^{}]], and limit

(b.1) lim sup _{}( ^{})( ( ))  ( ^{})(lim sup _{}) and
(b.2) lim sup _{}( ( ))  (lim sup _{})

Since by (b.1) _{}= ( ( )) is lim sup -pushable, we can apply Lemma 5.18, yielding for all ,

lim sup_{}^{}( ( )) ^{}lim sup_{}( ( ))

Combining this with (b.2), we can prove our goal

lim sup_{}^{}( ( )) ^{}(lim sup_{})

Uff! □

5.6 Type-Based Termination with Continuous Types

We replace the conditions for admissible (co)recursion types from Section 3.1.2 by the following, which use the new judgments for semi-continuity:

Γ fix_{}^{}-adm iff Γ :ord  = ( ( ^{}) ) :
and Γ :ord ^{}( ^{}) :
for some  with =
Γ fix_{}^{}-adm iff Γ :ord  = ( ( ^{}) ) :
and Γ :ord ^{}( ^{}) :
for some with =

Example 5.35 (Stream of natural numbers) We can now assign a precise type to the stream of natural numbers 0,1,….

mapStream :  ( )  Stream^{}Stream^{}
mapStream :=  fix_{0}^{}mapStream  (fst ) mapStream(snd )
nats  :  Stream^{}Nat^{}
nats  := fix_{0}^{}nats zero mapStream succ nats

Here are the types of some subexpressions of nats:

nats  : Stream^{}Nat^{}
succ  : Nat^{}Nat^{+1}
mapStream succ nats  : Stream^{}Nat^{+1}
zero  : Nat^{+1}
zero mapStream succ nats : Stream^{+1} Nat^{+1}

Since Stream^{}Nat^{}is upper semi-continuous (Example 5.29) it is admissible for corecursion. Note that it was not admissible according to the previous criterion (Section 3.1.2).

More examples for definitions that require the new criterion will be given in sections 6.1 (breath-first traversal of finitely branching trees), 6.4, (equality for monadic lists), 6.5 (a generic merge function), and 6.7 (transitivity of simple subtyping derivations).

5.7 Related and Future Work

The author [Abe03] has investigated admissible recursion types on the basis of slightly different concept. Roughly, lower semi-continuity of is replaced by the weaker condition (1) ( ) sup_{}and upper semi-continuity by the weaker condition (2) lim inf _{}( ). He shows the following main lemma: If ( ) sup_{}and lim inf _{}( ), then lim inf _{}( ( ) ( ))

( ) ( ). One could think that, since the conditions are weaker, more types are admissible. But the opposite is the case. Since (1) distributes only over a product ( ) ( ) if and are monotonic, products that involve an antitonic component are rejected by the syntactic calculus “cocont” which incarnates (1). However, in this thesis such types, for instance, List^{}(Nat^{}) (Nat^{}Bool), are accepted as lower semi-continuous.

Pareto [Par00] has investigated properties of types similar to semi-continuity. His setting differs considerably from ours: He considers only fixed-points of type constructors that are reached at iteration . These are inductive types without embedded function spaces, and strictly positive coinductive types. Size variables range over natural numbers and, consequently, ( ) quantifies only over natural numbers. However, for certain the variable may be instantiated by : Pareto describes a class of valid types which he calls - undershooting. These types have the property lim inf _{}( ) ( ). Function types are -undershooting if their codomain is so and if their domain is -overshooting, ( ) lim inf _{}( ). We have generalized the term - overshooting to arbitrary limit ordinals and called it lower semi-continuous. Also, we have demonstrated that our notion of upper semi-continuity, which uses lim sup , is as useful as Pareto’s notion of -undershooting, which uses lim inf .

We have shown that, in contrast to Pareto, we rightfully refuse inductive types as preservers of upper semi-continuity, since we allow embedded function spaces in inductive types.

We have given a syntax-directed derivation system for semi-continuous types. This was possible since we also created the new concepts of lim sup -pushable and lim inf -pullable type constructors on the semantical side. Our calculus is still weak on the higher-order features, and this is an area of future research. Ideally, we could extend our annotation of function kinds to express how a lim sup could be pushed into or a lim inf could be pulled out of a constructor. Then we would not need special rules for , , etc, but the kinding of these constants would take care of continuity properties—as it does currently with variance properties (polarities + , , and ).

116 CHAPTER 5. CONTINUITY

Examples

In this chapter, we present several examples, some of which exhibit an interesting recursion scheme (breadth-first traversal in Section 6.1, normalization procedures in sections 6.2 and 6.3, generic programming in Section 6.5) and others that are interesting for theoretical reasons (impredicative datatypes in Section 6.6, inductive proofs in Section 6.7). Pareto provided many functions on natural numbers, lists, and streams in his thesis [Par00]. Most of these are also typable in F_{}, except those that use addition of size variables, what we do not support.

In the examples we use syntactic sugar like pattern matching, which is a conservative extension of F_{}. It can be reduced to the primitives as described in section 2.4 of the article [AMU05].

6.1 Breadth-First Tree Traversal

Breadth-first traversal of a tree is not a structurally recursive program. In the following, we will refine the standard definition such that it is typable in F_{}.

Recall that in Haskell, [a] is the type of lists with constructors nil :: [a]

and (:) :: a -> [a] -> [a] and a function (++) :: [a] -> [a] -> [a],

which concatenates two lists. Since in Haskell least and greatest solutions of type equations coincide, there is no distinction between inductive and coinductive types, and [a] contains finite and infinite lists. For this example, we mean only finite lists. Rose trees are finitely-branching labeled trees with one constructor Rose :: a -> [Rose a] -> Rose a. A rose forest is a list of rose trees. Breadth-first flattening of a rose forest can be implemented as follows:

data Rose a = Rose a [Rose a]
bf0 :: [Rose a] -> [a]
bf0 [] = []
bf0 (Rose a rs : rs') = a : bf0 (rs' ++ rs)

Other breadth-first operations like breadth-first left or right folding can be expressed similarly. The definition of bf0 uses general recursion, since the recursive argument rs' ++ rs is not a subterm of Rose a rs : rs'. Termination could be shown by a decreasing measure: the number of Rose constructors in the forest. We show termination by massaging the definition until it fits our type system.

Looking a bit closer, we see that the traversal of the forest can be separated into phases: In the first phase, we process the roots of all rose trees. In the next phase, we do the same for the subtrees which emerged by cutting the roots in the first phase. Etc.

step :: [Rose a] -> ([a], [Rose a])
step [] = ([], [])
step (Rose a rs' : rs) =
    let (as, rs'') = step rs
        in  (a : as, rs' ++ rs'')

The step function makes such a run over the forest, returning a list of roots and the subforest. It is a simple iterative function and returns rose trees which are strictly less tall than the input trees. This is recognized by its typing in F_{}:

Rose : ord ^{+} ^{+}
Rose :=  _{}^{}List^{}
step :  List^{}(Rose^{+1} ) List^{}List^{}(Rose^{})
step := fix_{0}^{}step match with
nil  nil nil
cons rs^{}rs  match steprs with
as rs^{}cons as append rs^{}rs^{}

The type ( ) = List^{}(Rose^{+1} ) List^{}List^{}(Rose^{}) of the recursion is admissible, the second size variable does not interfere with admissibility.

Iterating step, we can perform a complete breadth-first traversal.

bf1 :: [Rose a] -> [a]
bf1 rs =
    let (as, rs') = step rs
        in as ++ bf1 rs'

However, its type ( ) = List^{}(Rose^{}) List^{}is not admissible for recursion. And indeed, bf1 is not terminating on the empty forest, which means that it eventually loops on every input. If we introduce a special clause for the empty forest, we regain termination.

bf2 :: [Rose a] -> [a]
bf2 [] = []
bf2 rs =
    let (as, rs') = step rs
        in as ++ bf2 rs'

But since we have not improved on the type of bf2, our type system will still reject it. We need to make explicit that we deal with non-empty forests in the recursion.

bf3 :: [Rose a] -> [a]
bf3 []     = []
bf3 (r:rs) = bf3' r rs
bf3' :: Rose a -> [Rose a] -> [a]
bf3' r rs =
    case step (r:rs) of
        (as, [])       -> as
        (as, r' : rs') -> as ++ bf3' r' rs'

The recursion in function bf3' can be given the type

( ) = Rose^{}List^{}(Rose^{}) List^{}

which is admissible in the extension of F_{}introduced in Chapter 5. For this, we have to show

: : ord; ^{}Rose^{}List^{}(Rose^{}) List^{}:

The non-obvious part of this goal is to show that List^{}(Rose^{}) is lower semicontinuous. In the following derivation, let Γ := : : ord. We further save space by dropping inessential parts of the derivation and its judgements.

\begin{matrix}Γ;  ^{}1 + \\ Γ;  ^{}List^{} \end{matrix}

Γ; ^{}List^{}

Γ; ^{}: ord

Γ; ^{}Rose^{}

Γ; ^{}

Γ; ^{}1 + Rose^{}

Γ; ^{}List^{}(Rose^{})

As a thumb rule, a type is lower semi-continuous, if its composed only of constant types, sum, product, and strictly positive inductive types.

This is the encoding of bf3' in F_{}:

bf_{3}^{}:  Rose^{}List^{}(Rose^{}) List^{}
bf_{3}^{}:= fix_{0}^{}bf rs match step (cons rs) with
as nil  as
as cons ^{}rs^{}append as(bf ^{}rs^{})

We can assign the following types:

bf  : Rose^{}List^{}(Rose^{}) List^{}
: Rose^{+1}
rs  : List^{}(Rose^{+1} )
cons rs  : List^{}(Rose^{+1} )
step (cons rs) : List^{}List^{}(Rose^{})
: Rose^{}
rs^{}: List^{}(Rose^{})
bf ^{}rs^{}: List^{}

Looking at bf3 we recognize that step is only called with non-empty forests. This enables the following optimization:

step4 :: Rose a -> [Rose a] -> ([a], [Rose a])
step4 (Rose a rs') []     = ([a], rs')
step4 (Rose a rs') (r:rs) =
    let (as, rs'') = step4 r rs
        in  (a : as, rs' ++ rs'')
bf4' :: Rose a -> [Rose a] -> [a]
bf4' r rs =
    case step4 r rs of
        (as, [])       -> as
        (as, r' : rs') -> as ++ bf4' r' rs'

We have successfully turned breadth-first traversal into a program which is accepted by our type system, by exhibiting a structure that was implicit in the original program. Well, the resulting program is much longer than the original, have we gained anything? Indeed, the refined program runs even faster than the original! For a literal translation of these programs into SML/NJ, Version 110.0.7, I have obtained the following running times on a SuSE Linux 9.1 system with an Intel\begin{matrix}r \\ ◯ \end{matrix} Pentium\begin{matrix}r \\ ◯ \end{matrix} III 1066MHz Mobile CPU and 256 MB system RAM.

Depth   Size    Rep     bf0     bf2     bf4
1       2       1000000 0.112   0.128   0.107
2       5       318641  0.119   0.136   0.105
3       16      52006   0.092   0.081   0.075
4       65      5281    0.109   0.034   0.032
5       326     371     0.176   0.013   0.012
6       1957    20      0.380   0.006   0.005
7       13700   1       1.984   0.006   0.005

The first two columns display quantitative information about traversed rose trees and the third column the number of repetitions. The remaining columns list the running times of the three programs in seconds. The speed-up can be 6.2. CONTINUOUS NORMALIZATION OF INFINITE DE BRUIJN TERMS121

explained by a more economic use of concatenation: The original program appends each subforest immediately to the (possibly very long) traversed forest, which can be a quite expensive operation. The refined programs only prepend (relatively short) subforests to an intermediate forest, which will be the traversed forest in the next phase. This is, in comparison, a cheap operation.

6.2 Continuous Normalization of Infinite De Bruijn Terms

Whether a normalizer/evaluator terminates depends on the object language and on the object expression that is to be evaluated. Usually, an evaluator cannot be implemented in a total meta language. In Section 6.3 we will present an exception: normalization of simply typed lambda-terms can actually be implemented in F_{}. But even evaluators for partial object languages, which might be invoked on non-terminating object programs, can be implemented in F_{}using coinduction. The trick is to produce the result step by step, and if no new piece of output can be guaranteed in the next step, instead produce a tick, which means wait for more output. (Of course, nothing guarantees that there will not be an infinite succession of ticks.) Such evaluation techniques are known under the slogan continuous normalization in proof theory and have been introduced by Mints [Min78] for the sequent calculus and adopted for natural deduction style term systems by Ruckert [Ruc85] and Schwichtenberg [Sch98], who built upon Buchholz’s infinite notations of sequent proofs [Buc91].

Aehlig and Joachimski [AJ05] describe continuous normalization of infinite -terms by guarded corecursion in the sense of Coquand [Coq93]. They give the following grammar for infinite de Bruijn terms with two “repetition” symbols and [AJ05, page 43] .

Λ_{}^{co} ::=^{co}

(Herein, denotes a de Bruijn index.) After defining substitution [ ] of for the 0th variable in , they give the following recursive definition of a function @, which continuously -normalizes the term (whereis a possibly empty, finite list of terms)[AJ05, page 46].

\begin{matrix}@ & ( _{1}  _{}) = & ( _{1}@()) ( _{}@()) \\ ( ) @ & ( )  = & ( [ ]@) \\ ( ) @ & ()  = & ( @()) \\ ( ) @ & = & ( @( )) \\ ( ) @ & = & ( @) \\ ( ) @ & = & ( @) \end{matrix}

Since each recursive call is under a term constructor, these equations define a corecursive function according to the guarded-by-constructors principle [Coq93, Gim95]. The constructors and do not contribute to the semantics of a lambda-term, but act as a notification that computation is still ongoing, but the outermost constructor of the lambda-term is not yet known. The symbol is produced whenever an application is evaluated (fourth equation), the symbol when a -reduction has been performed. It is remarked that continuous normalization could be defined without the -constructor. Then, the recursive call in the second equation is no longer under a constructor, thus, violates the guardedness condition. But the recursive call is justified since the length of the second argument has been decreased. Hence, the “termination” argument is lexicographic: Either the definedness of the output is increased (the second argument might be increased, as in the case of application), or the definedness of the output is not increased, but the size of the second argument is decreased. To make this precise, we express the normalization algorithm in F_{}.

In F_{}, we can define a coinductive type dB : ord with the following constructors:

var :  Nat dB^{+1}
abs :  dB^{}dB^{+1}
app :  dB^{}dB^{}dB^{+1}
rep :  dB^{}dB^{+1}

We assume we have already defined substitution subst : dB^{}dB^{}dB^{} (such that subst returns [ ]) and the library function for lists,

foldl :  (  )  List^{}
foldl [ _{1}  _{}] = _{1}  _{}

where [ _{1} _{}] denotes, as in ML and Haskell, the list cons _{1} ( cons _{}nil), and is a binary operation written infix. Then we can implement the normalization function @ by the following definition:

napp :  dB^{}List^{}dB^{}dB^{}
napp := fix_{2}^{}napp_{0}

fix_{1}^{}napp_{1}

match with

var  foldl ( ^{}app ^{}(napp_{0} nil))
abs  match with
nil  abs (napp_{0} nil)
cons ^{}napp_{1} (subst ) ^{}
app  rep (napp_{0} (cons ))
rep  rep (napp_{0} )

This definition is well-typed, since we can assign the following types to variables and subexpressions:

napp_{0}  :  dB^{}List^{}dB^{}dB^{}
napp_{1}  : dB^{}List^{}dB^{}dB^{+1}
: dB^{}
: List^{+1} dB^{}
: dB^{+1} dB^{}
app ^{}(napp_{0} nil) : dB^{+1}
foldl ( )  : dB^{+1}
abs (napp_{0} nil) : dB^{+1}
: List^{}dB^{}
napp_{1} (subst ) ^{}: dB^{+1}
rep (napp_{0} )  : dB^{+1}

An equivalently precise type of napp is the instantiation dB^{}List^{}dB^{} dB^{}, but we used the size variables and to indicate that napp is defined by lexicographic induction over ( ).

Remark 6.1 The function napp’s modulus of continuity is not the identity; we cannot assign to it the more precise type dB^{}List^{}dB^{}dB^{}. This would require subst to be of type dB^{}dB^{+1} dB^{+1} which is clearly invalid: if in the call subst , the first argument does not contain the 0th variable, then the result is which only has type dB^{}. Hence, the most precise type for subst is dB^{}dB^{}dB^{}.

6.3 Normalization of Simply-Typed De Bruijn Terms

We continue the example of Section 3.2.7. Simple types over a fixed type Atom of base types can be represented by the following constructors, which are easily definable F_{}:

Ty  : ord ^{+}
atom :  Atom Ty^{+1}
arr  :  Ty^{}Ty^{}Ty^{+1}

Joachimski and Matthes [JM03] describe a normalization procedure for simplytyped -terms; a similar algorithm has been found by Watkins, Cervesato, Pfenning, and Walker [WCPW03] for a term language of intuitionistic linear logic. At its heart lies an operation @ ^{}which produces a the -normal form of where and are normal and is of type . It uses a normalizing substitution function [ : ] which returns the normal form of the substitution [ ] if and are normal and is of type . The termination order of these mutual recursive functions is the lexicographic product of and .

( : )@ ^{}= [ : ]
( )@ ^{}=
[ : ]( : ) =  : [ : ]  w. l. o. g.,  FV( ) and =
[ : ]( )  = ^{}([ : ] )  if ^{}:= [ : ] neutral
= ^{}@([ : ] )^{}otherwise (then is smaller than )
[ : ]  = ^{}if =
=  otherwise

The result of substitution into a neutral term is either a neutral term or a normal term plus its type. We encode these alternatives in the type Res^{}, where is an upper bound on the size of the type and is the set of free variables which might occur in the result term.

Res  : ord ^{+} ^{+}
Res  :=  (1 + Ty^{}) TLam^{}
res_{Ne}  :  TLam^{}Res^{}
res_{Ne}  :=  inl
res_{Nf}  :  Ty^{}TLam^{}Res^{}
res_{Nf}  :=  inr
weak_{Res} :  Res^{}Res^{}(1 + )
weak_{Res} :=  map_{TLam} inr

The function weak_{Res} lifts the free variables in a result term by one (the function map_{TLam} is defined in Section 3.2.7).

The implementation of [ : ] is problematic, since for our encoding of de Bruijn terms only of all free variables is directly implementable. Substitution of a single variable is then implemented as a special case of parallel substitution. But for the termination of normalizing substitution, the size of type is important, so we expose it in the mapping .

( : )@ ^{}= ( _{0}[  ^{}])
( )@ ^{}=
( : ) ^{}=  : ( [  ])^{}w. l. o. g., singular in
( ) ^{}= ^{}( ^{})  if ^{}:= ^{}neutral
= ^{}@( ^{})^{}otherwise (then is smaller than )
= ( )

In the first line, _{0} denotes the identity substitution. A sharp look reveals that the mapping assigns exactly to one variable a non-trivial term, namely to , all other variables are mapped to themselves. A generalization of this invariant can be expressed in the type Subst^{}of :

Subst : ord ^{+} ^{}^{+}
Subst :=  Res^{}
sg_{Subst} :  TLam^{}Ty^{}Subst^{}(1 + )
sg_{Subst} :=  mx match mxwith
inl  res_{Nf}
inr  res_{Ne} (var )
lift_{Subst} :  Subst^{}Subst^{}(1 + ) (1 + )
lift_{Subst} := rho mx match mxwith
inl  res_{Ne} (var (inl ))
inr  weak_{Res} (rho )

The call sg_{Subst} : Subst^{}(1 + ) corresponds to _{0}[ ^{}]; it generates a substitution which maps the variable in 1 to res_{Nf} and the variables in to res_{Ne} (var ). The extension [ ] of a substitution is implemented by lift_{Subst} rho.

tm  :  Res^{}TLam^{}
tm  :=
abs_{Res} :  Ty^{}Res^{}(1 + ) Res^{}
abs_{Res} :=  inl abs (tm )
app_{Nf} :  Ty^{}TLam^{}TLam^{}TLam^{}
app_{Nf} := fix_{0}^{}app

let subst =

fix_{0}^{}subst rho match with

abs  abs_{Res} (subst (lift_{Subst} rho))
var  rho
app  match subst rhowith
res_{Ne} ^{}res_{Ne} (app ^{}(tm (subst rho)))
res_{Nf} (arr ) ^{}res_{Nf} (app ^{}(tm (subst rho)))

in match with

abs _tm (subst (sg_{Subst} ))
var _app
app __app

The matching of := subst rho is not complete, we have omitted the case res_{Nf} (atom ) ^{}. This case is excluded by an invariant we cannot express in our type system: that , and also the parallel substitution of have function type. In practice, this clause is never needed, so we could return anything suitable.

The body of app_{Nf} is quite complex; to increase readability we have used a let = in construct as syntactic sugar for ( ) . First we consider the typing of subst:

app  : Ty^{}TLam^{}TLam^{}TLam^{}
subst : TLam^{}Subst^{+1} Res^{+1}
: TLam^{+1}
rho  : Subst^{+1}
: Ty^{}
: TLam^{}(1 + )
lift_{Subst} rho  : Subst^{+1} (1 + ) (1 + )
subst (lift_{Subst} rho) : Res^{+1} (1 + )
abs_{Res} ( )  : Res^{+1}
:
rho  : Res^{+1}
: TLam^{}
subst rho  : Res^{+1}
tm (subst  ) : TLam^{}
res_{Ne} (app ^{}( )) : Res^{+1}
arr  : Ty^{+1}
: Ty^{}
app ^{}( )  : TLam^{}
res_{Nf} ( )  : Res^{}Res^{+1}
subst  :  TLam^{}Subst^{+1}  Res^{+1}

Well-typedness of app_{Nf} now follows:

app  : Ty^{}TLam^{}TLam^{}TLam^{}
subst : TLam^{}Subst^{+1} Res^{+1}
: Ty^{+1}
: TLam^{}
: TLam^{}(1 + )
sg_{Subst}  : Subst^{+1} (1 + )
subst ( )  : Res^{+1}
tm ( ) app  : TLam^{}

6.4 Data Types with Higher-Order Parameters

Type-based termination, unlike termination using structural term orderings, scales effortlessly to data types with higher-order parameters. For example, consider the type of monadic lists

MList : ord ^{+} ( ^{+} ) ^{+} ^{+}
MList :=  ^{}1 +

with constructors

mnil :  :( ^{+} )
MList^{+1}
mnil := inl
mcons :  :( ^{+} )
(MList^{+1} ) MList^{+1}
mcons := ma mas inr ma mas

Equality-test for monadic lists MList^{}must necessarily be parameterized by an equality for and an equality transformer for , meaning a function which turns an equality for an arbitrary type into an equality for type .

Eq  :
Eq  :=  Bool
eqMList :  ( Eq Eq ( ))  Eq Eq (MList^{})
eqMList := meq eq fix_{0}^{}eqMList

match with

mnil mnil  true

mcons mamas

mcons mbmbs  meqeqmamb and
meqeqMListmasmbs
_false

The function eqMList exhibits a funny recursion pattern: instead of having a recursive call in which the function is applied to some structurally smaller arguments, in the “recursive call” meqeqMList, it is passed itself as an argument to one of the function arguments. Now this behavior is surely problematic: If we do not know how meqhandles its argument, there is no way we could justify termination. For instance, the execution of meqeqMListcould involve an application of eqMListto some non-empty constant lists. In this case eqMList would clearly diverge. Fortunately, the parametric type Eq Eq ( ) of meq prevents such a use of eqMList. And indeed, eqMList is terminates on all inputs, since it is well-typed in F_{}:

eqMList  : Eq (MList^{})
: MList^{+1}
mas mbs  : (MList^{})
meq : Eq Eq ( )
meqeqMList  : Eq ( (MList^{}))
meqeqMListmasmbs : Bool

This was a first instance of a non-standard recursion behavior; in the next section we will see more such examples.

6.5 Generic Programming

Jansson and Jeuring [JJ97] and Hinze [Hin02] describe frameworks for polytypic and generic programming. In these, both types and values can be constructed by recursion on some index type. A common feature is that the behavior is only specified for the type and constructor constants like Nat, 1, + and , and this uniquely defines the constructed type or value. In the following we propose an ad-hoc extension by sized types, sized polytypic programming. This framework is good enough to model Hinze’s generalized tries [Hin00b], but whether it scales to other examples requires more research.

Type-indexed types are of kind-indexed kinds. A type-indexed constructor Type : has kind-indexed kind TYPE . In the polytypic framework, each such constructor Type and each such kind TYPE must obey the following laws:

TYPE ord  = ord
TYPE _{1} ^{}_{2} = TYPE _{1} ^{}TYPE _{2}
Type  =
Type = Type
Type  = Type Type
Type _{}= _{TYPE}
Type s  = s
Type  =

This means, function kinds are always mapped to function kinds, application to application, fixed point to fixed point etc. Hence, a kind-indexed kind TYPE is determined by the value of TYPE , and a type-indexed type Type by the value of Type for the constants which appear in .

Proposition 6.2 (Well-kindedness of type-indexed types) Let Σ a signature of constructor constants. If Type : TYPE for all ( : ) Σ, and :: _{1} : 1 _{1} _{}: _{}_{}: , then _{1} : _{1}TYPE _{1} _{}: _{}TYPE _{} Type : TYPE .

Proof. By induction on . □

Remark 6.3 Note that the presence of polarities restricts the choices for Type . However, if index types are constructed in a signature without polymorphism and function space, as it is usual in the generic programming community, all function kinds are covariant and we do not have to worry about polarities.

Example: finite maps via generalized tries. Hinze [Hin00b] defines generalized tries Map by recursion on . In particular, Map : is the type of finite maps from domain to codomain . The following representation using type-level can be found in his article on type-indexed data types [HJL04, page 139].

MAP  :=  ^{+}
Map Int  :=  efficient implementation ofInt _{fin}
Map Char :=  efficient implementation of Char _{fin}
Map 1  :=  1 +
Map +  :=  1 +
Map  :=  ( )

Well-kindedness of these definitions is immediate, except maybe for Map which must be of kind ( ^{+} ) ^{+} ( ^{+} ) ^{+} ( ^{+} ). For Map + we have used the variant of spotted products (or lifted products) which Hinze mentions in section 4.1 of his article [Hin00b]. This way we avoid that certain empty tries have a infinite normal form (see [Hin00b, page 341]) which requires lazy evaluation. The constructor for finite maps over strings can now be computed as follows:

Map List^{}Char

= Map  _{}1 + Char
=  _{^{+}}  Map + Map 1 (Map Map Char )
=  _{^{+}}  1 + (1 + ) Map Char ( )
(=  _{}1 + (1 + ) Map Char )

For the last (and optional) step, we have applied -dropping (see Sec. 3.3.5), to turn the second-order fixed point into a first-order one. The matching kind is

MAP ord ^{+} = ord ^{+} ^{+}

Type-index values poly : are of kind-indexed types. These types Poly : are defined by recursion on , and is just a parameter. The kind must fit into the grammar

::= ord ^{}_{1} ^{}_{2}

Note that Hinze, Jeuring, and Löh [HJL04, page 142] allow kind-indexed types Poly with several constructor parameters. For our examples, however, a single parameter is sufficient.

The following laws hold for all constructor-indexed values poly : and kind-indexed types Poly : in the framework:

Poly :ord ^{}=  :ord Poly :
Poly : _{1} ^{}_{2}  =  : _{1} Poly : _{1} Poly : _{2}
poly  =
poly  : ord  = poly
poly  : _{1}  _{2}  =  poly  where _{1} = ord
poly _{}= fix_{}^{}for some
poly  = poly poly  where =

In order to ignore size expressions, which do not contribute to the computational behavior of the generic value poly , we ignore size abstractions and size parameters to fixed points. To make this work, the constructor parameter must be in normal form, and constants of the signature should not take a size argument. A polytypic value of an (co)inductive constructor is (co)recursive. The parameter in fix_{}^{}must be given appropriately.

Note that kind-indexed types need not be compositional, i. e., in general Poly = Poly Poly does not hold. On the other hand, they are parametric in the constructor argument, since only a single equation Poly : = is given by the user, which does not analyze the structure of .

Example: finite map lookup. We give an adaption of Hinze’s generic lookup function to our setting. Herein, we use the bind operation = for the Maybe monad 1 + . It obeys the laws inl() = ^{+} inl() and inr = + . Note that in this section, we will write pairs as ( ) instead of and the empty tuple as () instead of , to avoid confusions with the notation for type indices.

Lookup :  :=  Map  1 +
lookup 1  :  1 1 + 1 +
lookup 1  :=
lookup +  :  : Lookup  : Lookup
+ 1 + (Map  ) (Map  ) 1 +
lookup +  := la lb ab tab tab = (ta tb)
match abwith
inl  la ta
inr  lb tb
lookup  :  : Lookup  : Lookup

Map (Map ) 1 +

lookup  := la lb ( ) tab la tab = tb lb tb

All these definitions are well-typed, which is easy to check since there are no references to sizes.

Example: lookup for list-shaped keys. The previous definitions determine the instance of the generic lookup function for the type constructor of lists.

lookup List

: Lookup List
:  : Lookup  Lookup List^{}
:  : Lookup  List^{}Map List^{}1 +
:  : Lookup  List^{}( ^{}1 + (1 + ) ) 1 +

lookup List

= lookup  ^{}1 +
= lookup_{K} fix_{0}^{}lookup lookup + lookup 1 (lookup lookup_{K}lookup)
= lookup_{K} fix_{0}^{}lookup  = ( )

match with

nil
cons ^{}lookup_{K} =  ^{}lookup ^{}^{}

Note that the type of lookup List mentions the size variable twice, as index to both inductive arguments. This makes sense, since the length of the search keys determines the depth of the trie. Welltypedness can be ensured on an abstract level:

lookup_{K}  : Lookup
lookup  : Lookup List^{}
lookup lookup_{K}lookup =:  : Lookup List^{}
lookup + lookup 1 =: : Lookup 1 + List^{}
: Lookup List^{+1}
fix_{0}^{}lookup  : Lookup List^{}

Finally, the type Lookup List^{}is admissible for recursion on the first argument, since the first argument is of shape ^{}and the whole type Lookup List^{} is upper semi-continuous in .

Trie merging. Hinze [Hin00b] presents three elementary operations to construct finite tries: empty, single, and merge. In the following we replay the construction of merge in our framework, since it exhibits a most interesting recursion scheme.

First we define the type Bin for binary operations on and a function comb which lifts a merging function for to a merging function for 1 + .

Bin :  ^{}
Bin :=
comb :  (  ) (1 + 1 + 1 + )
comb :=  _{1} _{2} match ( _{1} _{2}) with
(inl() _)  _{2}
(_inl())  _{1}
(inr _{1} inr _{2})  inr ( _{1} _{2})

The following definitions determine a generic merging function.

Merge :  :=  Bin Bin (Map  )
merge 1  : Merge 1
merge 1  := comb
merge +  :  Merge  Merge  Bin
Bin (1 + Map  Map  )
merge +  := ma mb comb

(ta_{1} tb_{1}) (ta_{2} tb_{2}) (ma ta_{1} ta_{2} mb tb_{1} tb_{2})

merge  :  Merge  Merge  Bin

Bin (Map (Map ))

merge  := ma mb ma(mb )

The instance for list tries can be computed as follows:

merge List

: Merge List
:  Merge  Merge List^{}
:  ( Bin Bin (Map  ))

Bin Bin (Map List^{})

merge List

= merge  ^{}1 +
= merge_{K} fix_{1}^{}merge merge + merge 1 (merge merge_{K}merge)
= merge_{K} fix_{1}^{}merge comb
(mv_{1} _{1}) (mv_{2} _{2}) (comb mv_{1} mv_{2} merge_{K}(merge ) _{1} _{2})
[= merge_{K} fix_{0}^{}merge comb
(mv_{1} _{1}) (mv_{2} _{2}) (comb mv_{1} mv_{2} merge_{K}merge _{1} _{2})]

In the last step, we have decreased the rank of recursion by -dropping. Surprisingly, recursion happens not by invoking mergeon structurally smaller arguments, but by passing the function itself to a parameter, merge_{K}. Here, typebased termination reveals its strength; it is not possible to show termination of merge List disregarding its type. With sized types, however, the termination proof is again just a typing derivation, as easy as for lookup List . We reason again on the abstract level:

merge_{K}  : Merge
merge  : Merge List^{}
merge merge_{K}merge =:  : Merge List^{}
merge + merge 1 =: : Merge 1 + List^{}
: Merge List^{+1}
fix_{1}^{}merge  : Merge List^{}

The type Merge List^{}is admissible for recursion on the second argument (the first argument is of type Bin ): The whole type is of shape Bin ^{} for some which does not depend on the size variable . Hence, the type is upper semi-continuous.

Merging bushy tries. An even more dazzling recursion pattern is exhibited by the merge function for “bushy” tries, i. e., finite maps over bushy lists.

Bush  : ord ^{+} ^{+}
Bush  :=  _{^{+}}  1 +  ( )
Map Bush : ord ^{+} ( ^{+} ) ^{+} ( ^{+} )
Map Bush =  _{( ^{+} )^{+} ( ^{+} )}  1 + (1 + ) ( ( ) )

The merge function for bush-indexed tries can be derived routinely:

merge Bush

= merge ^{}1 + ( )
= fix_{2}^{}merge merge_{K}

merge + merge 1 (merge merge_{K}(merge(mergemerge_{K})))

= fix_{2}^{}merge merge_{K}

comb (mv_{1} _{1}) (mv_{2} _{2})

(comb mv_{1} mv_{2} merge_{K}(merge(mergemerge_{K}) ) _{1} _{2})

The recursion pattern of merge Bush is adventurous. Not only is the recursive instance mergepassed to an argument to the function merge_{K}, but also this function is modified during recursion: it is replaced by (mergemerge_{K}), which involves the recursive instance again! All these complications are “miraculously” resolved by typing!

Related work. Hinze, Jeuring, and Löh [HJL04] present generic programming with type-indexed datatypes and type-indexed value both in Haskell and the higher-order polymorphic -calculus with a standard model. Altenkirch

[Alt01] investigates the representation of total functions over inductive types as higher-order coinductive types. He establishes isomorphisms in a categorical semantics.

6.6 Impredicative Data Types

Some kinds of structural orderings for termination do not scale to impredicativity. On such ordering is described by Coquand [Coq92] and implemented in the termination checker foetus [AA02, Abe99]. It rests on the axioms

c  if c is a data constructor, and

In the presence of datatypes with impredicativity, this ordering is not wellfounded. Coquand demonstrates this using a type V with a single constructor

c : ( ) V

With id = we obtain the cycle c id id id (c id) = c id. Hence, a termination checker based on this ordering would accept the recursive program (c ) = ( (c )). Let us analyze this paradox with sized types:

V  : ord ^{+}
V  :=  _{}^{}_
loop :  V^{}0
loop := fix_{0}^{}( )

Type-based termination rejects this program: We have

\begin{aligned} & : & \\ & : & V^{+1} \\ & : & V^{+1} \end{aligned}

but : V^{}0 does not accept this argument.

6.7 Inductive Proofs as Recursive Functions

In this section, we will demonstrate how F_{}can be used to certify termination of recursive functions which correspond to proofs by induction in some dependent type theory.

As example theorem, we consider transitivity for a simple inductively defined subtyping relation. A similar example has been given by Wahlstedt [Wah04], who uses size-change termination [LJBA01].

We consider a language of simple types with a least type and a greatest type .

Ty ::=

Subtyping is defined inductively by the following rules:

SBot \overline{:}  STop \overline{:}

SProd \frac{_{1} : _{2}  _{1} : _{2}}{_{1} _{1} : _{2} _{2}}  SArr \frac{_{2} : _{1}  _{1} : _{2}}{_{1}  _{1} : _{2}  _{2}}

We represent this subtyping relation by an inductive family Sub : Ty Ty Prop with four constructors:

SBot : Sub
STop : Sub
SProd : Sub _{1} _{2} Sub _{1} _{2} Sub ( _{1} _{1}) ( _{2} _{2})
SArr : Sub _{2} _{1} Sub _{1} _{2} Sub ( _{1}  _{1}) ( _{2}  _{2})

We have suppressed the arguments of type Ty for all constructors: SBot and SBot take an additional hidden argument , and SProd and SArr take four hidden arguments _{1}, _{2}, _{1}, and _{2}.

The relation : is transitive, and it can be shown by induction on the sum of the heights of the two input derivations. In type theory, the proof can be implemented as a recursive function

trans : Sub _{1} _{2} Sub _{2} _{3} Sub _{1} _{3}

Again, we consider _{1}, _{2}, and _{3} hidden arguments of trans. Each case in the proof of transitivity corresponds to one pattern matching clause of trans. Using the type dependencies, the following matching is complete:

trans SBot  _= SBot
trans _STop  = STop
trans (SProd _{1} _{1}^{}) (SProd _{2} _{2}^{}) = SProd (trans _{1} _{2}) (trans _{1}^{}_{2}^{})
trans (SArr _{1} _{1}^{}) (SArr _{2} _{2}^{}) = SArr (trans _{2} _{1}) (trans _{1}^{}_{2}^{})

This function is not just defined by structural recursion on the first argument or by lexicographic recursion on both arguments, since in the last line, a subterm ( _{2}) of the second argument appears as first argument to a recursive call (trans _{2} _{1}) and vice versa. A valid termination measure would be the sum of the size of both arguments. We can also certify its termination by typing it in F_{}. To this end, we have to erase all dependencies.

In F_{}, we set Sub^{}:= ^{}1 + 1 + + . The four constructors are now definable:

SBot :  Sub^{+1}
STop :  Sub^{+1}
SProd :  Sub^{}Sub^{}Sub^{+1}
SArr :  Sub^{}Sub^{}Sub^{+1}

The recursive function can now be given the type

trans : Sub^{}Sub^{}Sub^{}

One problem remains: In F_{}, we have no partiality, but without dependencies, the four patterns defining trans do not cover the full value space. This problem can be mended by adding a catch-all clause trans __= SBot, or by extending F_{}by partiality. For instance, one could have four eliminations of the disjoint sum type, case_{}, for l r , with typing

case_{}:  +
case_{l} :  + ( )
case_{r} :  + ( )
case_{l r} :  + ( ) ( )

136 CHAPTER 6. EXAMPLES and the reduction rules

case_{l} (in_{l} )  ↣
case_{r} (in_{r} )  ↣
case_{l r} (in_{l} )  ↣
case_{l r} (in_{r} )  ↣

A term case_{}(in_{}) with would be considered neutral.

Extensions

In this chapter, we sketch some useful extensions of F_{}.

7.1 Mutual Recursion

Normal de Bruijn terms can be defined by two mutually recursive type constructors in Haskell:

data Ne a = Var a
          | App (Ne a) (Nf a)
data Nf a = Ne (Ne a)
          | Abs (Nf (Maybe a))

In F_{}, there is no notion of mutual recursion, but it can be simulated with nested recursion.^{1} For mutual type constructors, the standard encoding into nested inductive type constructors works smoothly:

NeF NfF : ( ^{+} ) ^{+} ( ^{+} ) ^{+} ^{+}
NeF  :=  +
NfF  :=  + (1 + )
Ne Nf : ord ^{+} ^{+}
Ne  :=  _{^{+}}^{}NeF ( _{^{+}} NfF )
Nf  :=  _{^{+}}^{}NfF ( _{^{+}} NeF )

1Nested is also called interleaving [AA00].

As usual, we can define the following data constructors:

var :  Ne^{+1}
var :=  inl
app :  Ne^{}Nf^{}Ne^{+1}
app :=  inr
ne :  Ne^{}Nf^{+1}
ne :=  inl
abs :  Nf^{}Nf^{+1}
abs :=  inr

To encode mutual recursion on the term level, we need to extend the type system of F_{}. We basically need a well-founded recursion rule and a bounded recursion rule:

ty-wf-rec

Γ fix_{}^{}-adm Γ : ord

Γ fix_{}^{}: ( :ord ( ) ( + 1))

ty-bd-rec \frac{Γ fix_{}^{}-adm Γ  : ord}{Γ fix_{}^{}: (  ( + 1))  ^{}}^{}s
Bounded quantification  :  is to be understood as usual. It has

been studied extensively in the last decade, e. g., by Pierce and Steffen [PS97, Ste98] and Duggan and Compagnoni [DC99]. In our calculus, we could add it through a constant and some defined notation:

\begin{aligned}_{}^{} & : & ^{}( ^{}) ^{+} \\ : & := & _{}^{}( ) \end{aligned}

Adding a top kind Top_{}: for all kinds (for ord it is ), we can then define usual quantification by _{}:= _{}^{}Top_{}. We replace the generalization and instantiation rules by the following:

ty-gen \frac{Γ  :  :}{Γ  : _{}^{}}ty-inst \frac{Γ  : _{}^{}Γ  :}{Γ  :}

Figure 7.1 displays the mapping terms of normal and neutral de Bruijn terms. The term map_{Nf} reuses the lifting operation from Section 3.2.7. We have used the standard encoding of mutual recursion into nested recursion, and it is compatible with our extension of F_{}as the following type assignment for map_{Nf} in Figure 7.1 shows.

Bounded and well-founded recursion can be combined into bounded wellfounded recursion.

ty-bd-wf-rec \frac{Γ fix_{}^{}-adm Γ  : ord}{Γ fix_{}^{}: (  (  ) ( + 1))  ^{}}^{}s

7.1. MUTUAL RECURSION 139 Mapping terms.

Map_{Ne} Map_{Nf} : ord ^{}
Map_{Ne}  :=  ( ) Ne^{}Ne^{}
Map_{Nf}  :=  ( ) Ne^{}Ne^{}
map_{NeF}  :  Map_{Nf} Map_{Ne} Map_{Ne}( + 1)
map_{NeF}  := map_{Nf} map_{Ne}  match with
var  var ( )
app  app (map_{Ne} ) (map_{Nf} )
map_{NfF}  :  Map_{Nf} Map_{Ne} Map_{Nf}( + 1)
map_{NfF}  := map_{Nf} map_{Ne}  match with
ne  ne (map_{Ne} )
abs  abs (map_{Nf} (lift ) )
map_{Ne} : Map_{Ne}
map_{Ne}  := fix_{1}^{}map_{Ne} map_{NeF} (fix_{1}^{}map_{Nf} map_{NfF} map_{Nf} map_{Ne}) map_{Ne}
map_{Nf} : Map_{Nf}
map_{Nf}  := fix_{1}^{}map_{Nf} map_{NfF} map_{Nf} (fix_{1}^{}map_{Ne} map_{NeF} map_{Nf} map_{Ne})

Type assignment for map_{Nf}.

map_{Nf} : Map_{Nf} assumption
assumption
map_{Ne}  : Map_{Nf}  assumption
map_{Nf}  : Map_{Nf}  instantiation
map_{NeF} map_{Nf} map_{Ne} : Map_{Ne}( + 1)
(fix_{0}^{}map_{Ne} )  : Map_{Ne}  ty-bd-rec
map_{Nf}  : Map_{Nf}  instantiation
map_{NfF} map_{Nf} ( ) : Map_{Nf}( + 1)  ty-wf-rec

Figure 7.1: Functoriality for normal de Bruijn terms.

The presence of bounded type assumptions  : in Γ, especially  for

ordinals, does not jeopardize our normalization result. The induction principle behind ty-bd-wf-rec can easily justified by transfinite induction. A more natural formulation of this rule would one using strict inequality of ordinals:

Γ fix_{}^{}-adm Γ : ord

Γ fix_{}^{}: (  (  )  )

But how to prove normalization in presence of strict inequality assumptions in Γ requires further thought.

Mutual Recursion Via Products. Alternatively, mutual recursion can be added as a new principle, realized via products. This has been carried out by Pareto [Par00, p. 152] and Xi [Xi02]. To implement mutual recursion on the constructor level we need product kinds.

7.2 More Admissible Types

Our criterion for types of recursive functions admits the type Nat^{}Nat^{} Nat^{}, e. g., as type of the minimum or maximum function for natural numbers, but not the isomorphic type Nat^{}Nat^{}Nat^{}. Using this type, the minimum function would be coded as follows:

min :  Nat^{}Nat^{}Nat^{}
min := fix_{0}^{}min match with
zero _zero
_zero  zero
succ ^{}succ ^{}succ (min ^{}^{})

However, in our reduction semantics, min is not strongly normalizing, since the pair ^{}^{}counts as a value and triggers unfolding of recursion:

min  ^{+} match succ (min ^{}^{})
+ match succ (match succ (min ^{}^{}))
+

The most promising solution to this problem is add patterns as a primitive language construct and to tie unfolding recursion to pattern matching:

min :  Nat^{}Nat^{}Nat^{}
min := fix_{0}^{}min { \atop }zero _zero _zero  zero succ ^{}succ ^{}succ (min ^{}^{}) { \atop }

The reduction semantics has to be adapted such that min is no longer a redex, only min zero and min zero , which both reduce to zero, and min succ ^{}succ ^{}, which reduces to succ (min ^{}^{}) in one step.

Since products of the form are isomorphic to Bool , one could imagine a type system which also accept the following, a little artificial, variant of the minimum function:

min :  (Bool Nat^{}) Nat^{}
min := fix_{0}^{}min match true false with
zero _zero
_zero  zero
succ ^{}succ ^{}succ (min( if then ^{}else ^{}))

Since a -abstraction is a value, this definition of min is not strongly normalizing for similar reasons as the first definition with products. However, in this case, it seems impossible to salvage strong normalization. But if one is only interested in the termination of closed programs, this definition is fine, and indeed, the type system of Hughes, Pareto, and Sabry [HPS96] accepts it.

142 CHAPTER 7. EXTENSIONS

Conclusion

In this thesis, I have presented a simple but powerful type system which certifies termination and productivity for higher-order functional programs with higher-rank polymorphism and higher-order and heterogeneous data types that can contain both infinitely deep and infinitely branching trees. Its practical applicability has been demonstrated by numerous non-trivial examples. It has been shown that the marriage of types with termination analysis can effortlessly treat the case of higher-order functional programs which are hard for termination analyses based on term orderings. The types paradigm has again proven an effective tool to structure program analysis.

Some problems have been left open in this thesis. For one thing, more work has to be done on models of F_{}. The current model proves strong normalization, but it does not give much information about the impredicative encodings of disjoint sum and product. It would be desirable to have a model where the impredicative encodings have semi-continuity properties, but it is unclear to me whether this can be achieved.^{1}

Also, the types-as-sets-of-evaluation-contexts model needs refinement. One would like that _{}_{}implies _{}for some , if the _{}are sets of evaluation contexts with certain closure properties and form a sequence of a certain form, e.g., a chain or a directed sequence. With that property, one could prove semi-continuity properties for the refined saturation model which was necessary for equi-coinductive types. Again, this is future research.

Finally, I am looking for a model of type-based termination and productivity that is simpler than the ones known to me: (1) types as sets of strongly normalizing terms (this thesis, Barthe et al. [BFG^{+} 04], Blanqui [Bla04]) and (2) types as upward closed subsets of a domain with -element (Pareto [HPS96, Par00]). It seems funny that in order to reason about terminating and productive functional programs, which never produce an undefined result, one either has to generalize evaluation to symbolic computation and speak about strong normalization, or one has to add a -element and show that it is never a result of a well-typed program. A promising direction is Xi‘s work [Xi02] which gives a much simpler call-by-value semantics. However, he cannot handle infinite objects like streams. Maybe coinductive types can be modeled as sets of evaluation contexts, as in this thesis, but on the basis of a simpler operational semantics, e. g., a big-step call-by-name semantics for closed programs.

1Christine Paulin-Mohring has told me that the impredicative encodings are not adequate— they contain junk.

8.1 Related Work

There is an abundant literature on termination. We will only consider a few recent publications. We divide them into two categories: papers which deal with fully automated termination checking, and those which presents methods how to (partially) automate termination proofs.

8.1.1 Termination Proofs

A very general method to define function is by well-founded recursion. Nordström has demonstrated its use in Martin-Löf Type Theory [Nor88]. In the Calculus of Inductive Constructions, this recursion scheme is an instance of primitive recursion over the accessibility predicate, which is the constructive version of well-foundedness and can be defined as an infinitely-branching inductive data type. Balaa and Bertot [BB00] demonstrate how to recover the fixed-point equation from well-founded recursion in Coq.

From a recursive function definition, an induction scheme can be extracted [Wal92, Hut92]. Each function clause corresponds to one case, and each recursive call in this clause to one induction hypothesis available in this case. One way to prove termination of the function is to first establish the induction scheme and use it to show termination. The second part can often be fully mechanized. In the following, we describe some works which follow roughly this technique.

In Higher-Order Logic, as implemented in the Isabelle [Pau90] interactive theorem prover, a fixed-point combinator WFREC for well-founded recursion is definable. Slind [Sli96] wrote the TFL package which translates recursive functions defined by pattern matching into WFREC-expressions, and extracts termination conditions as proof obligations. Special tactics attempt to discharge these obligations with the help of a user-supplied measure. This approach is very flexible and works quite well in practice. Unfortunately, it cannot be used to construct proofs by induction, since derivations are not first class objects in HOL and cannot be manipulated by functions (the Curry-Howard isomorphism breaks down).

A similar mechanism is implemented in PVS [ORS92]. With a recursive definition the user has to supply a termination measure and prove the arising termination conditions. PVS has powerful proof automation, hence, discharging the conditions causes in most cases not much trouble.

Bove and Capretta [BC05a] take a recursive definition and generate its inductive domain predicate such that the induction scheme associated to this predicate corresponds to the above describe induction scheme associated with the recursive function. The recursive definition is translated into Type Theory as a partial function which is well-defined on the inductive domain. To show that a function is total one has to prove that all values inhabit the inductive domain. Recently Bove and Capretta have extended their approach to higherorder domains [BC05b].

Bertot [Ber05] uses domain predicates to define corecursive stream filtering functions. He requires the selection predicate to hold infinitely often on the input streams to obtain productive output streams. Since “infinitely often” means at each point “eventually” and he uses an inductive definition of “eventually”, he can define the filtering function using recursion inside corecursion. With his technique he manages to define the Sieve of Eratosthenes by corecursion in Coq. Mixed recursion/corecursion is also possible in F_{}(see Huffman decoding example, Section 3.2.4), but to see that the Sieve of Eratosthenes is productive requires mathematical knowledge, which is beyond our system.

Ultrametric spaces and Banach’s fixed-point theorem. Buchholz [Buc05] investigates recursive and corecursive definitions as fixed-points of functionals on ultrametric spaces. For instance, streams of natural numbers form an ultrametric space with the equivalence relations _{}for ℕ defined by

0 ^{}true
+1 ^{}hd = hd ^{}and tl _{}tl ^{}

Banach’s fixed-point theorem guarantees such definitions to be well-defined if the underlying functional is contractive. Buchholz turns this principle into a system for “type-based termination” by decorating function arrows with moduli : ℕ ℕ. The modulus of a function expresses how well its arguments must be related for its results to be related, or more precisely,

^{}ℕ ^{}_{( )} ^{}= _{}^{}

Then, the tail function tl can be given type ^{+1} and stream construction

cons : ℕ ^{1} . In terms of Buchholz’ systems, F_{}is restricted to moduli of the form and uses a fixed ultrametric arising from the approximation of (co)inductive fixed points. I think Buchholz can simulate the simply-typed strictly-positive fragment of F_{}, but I am not sure whether he can define recursive functions over inductive datatypes with a closure ordinal .

A conceptual difference between rewriting in F_{}and Buchholz’ system is that in F_{}, fixed points are unrolled on demand, whereas in Buchholz’ system a term is given an amount of “fuel” and each fixed-point unrolling costs one unit. The amount of initial fuel depends on the modulus of the term and on how precise the result of the term should be approximated.

Buchholz does not treat polymorphism.

Gianantonio and Miculan [GM03] generalize ultrametric spaces further to ordered families of equivalences (OFE). Basically, there is a collection of equivalence relations indexed by any well-ordered set (in Buchholz’ case, this was always ℕ). Otherwise, their method is very similar to Buchholz’. Their main selling point is that they can treat mixed recursive/corecursive definitions; as the Huffman-decoder examples of Huffman decoding and prime numbers show (see sections 3.2.4 and 3.2.5), this is also possible in F_{}.

Finally, Matthews [Mat99] has explored the use of converging equivalence relations (CERs), which are a variant of OFEs to define corecursive objects in Isabelle. His results are similar to Gianantonio and Miculan’s.

8.1.2 Termination Checking

Size-change principle. Lee, Jones, and Ben-Amram [LJBA01] have coined the term size-change principle for termination: A program terminates on all inputs if every infinite call sequence … would cause an infinite descent in some data values. Checking size-change termination is in general PSPACE-complete, but with some restrictions it becomes polynomial [Lee02].

Jones and Bohr [JB04] apply size-change termination to closed lambda-terms under deterministic call-by-value evaluation. One lambda-expression calls another if the evaluation of the first depends on the evaluation of the second. Using an operational semantics with environments (explicit substitutions), they maintain the invariant that the set of subexpressions is not increased under evaluation and call. Since the initial lambda-expression has only a finite number of subexpressions, a call graph can be constructed on these using abstract interpretation. Sereni [Ser04], also with Jones [SJ05], refines the abstract interpretation and refutes the conjecture that the size-change principle certifies termination for all simply-typed closed lambda-terms [Ser05]. This suggests that (simple) typing and size-change are complementary principles.

The size-change termination analysis for closed lambda-expressions cannot directly be extended to open expressions since it hinges on the subexpressionproperty, which fails for open expressions: Let \overline{}denote the th Church numeral. Then \overline{}(\overline{}) has ( + ) subexpressions, but its evaluation, ^{}, has ( ) subexpressions.

In own work with Altenkirch [AA02], simple typing has been combined with a termination criterion based on call graphs which likens the one of Jones et al.In essence, it does not accept functions which swap their parameters in recursive calls, otherwise, it is isomorphic to Jones et al.. The tool foetus [Abe98] detects lexicographic termination orderings for simply-typed functional programs and inductive types.

Wahlstedt [Wah04] combines size-change termination with dependent types and first-order inductive datatypes. His normalization proof uses a reducibility semantics and Ramsey’s theorem.

Abstract interpretation and types. Telford and Turner [TT00, TT97] check termination and productivity of recursive functions by an abstract interpretation. They track size-change on an abstract domain and can handle first-order functional programs quite well. However, type-based termination seems the more promising approach, since then type analysis and size analysis are integrated into one language and can benefit from each other.

Amadio and Coupet-Grimal [ACG98] extend the simply-typed -calculus by non-nested coinductive types and describe a type system for well-defined corecursion via a fixed-point combinator. The typing rule for fixed-points is motivated by transfinite induction, but no closure ordinal is provided. Soundness of the system is proven through a model of partial equivalence relations (PER). The PER model validates an equality consisting of , , and fixed-point unfolding axioms, plus a uniqueness theorem for fixed points. They also give confluent and fixed-point reduction rules, whose termination is shown via a model of reducibility candidates. Their system subsumes Coquand’s guard condition [Coq93], but since it does not have size polymorphism, it is outmatched by Barthe et al. [BFG^{+} 04] and my system ^{fix} [Abe03], which in turn are both subsumed by this thesis.

McBride, the principal implementor of Epigram [MM04] seems to follow the slogan every total program is structurally recursive, i. e., he tries to unveil hidden structures and defuse functional programs to arrive at components which are all primitive recursive. For instance, as already noted by Turner [Tur95], quick-sort is just a deforested version of tree-sort. Altenkirch, McBride, and McKinna [AMM05] defuse also merge-sort by introducing some kind of balanced tree as intermediate structure. Sized types, as presented in this thesis, can elegantly capture structural recursion, but can do more than that. By expressing size relations between input and output of functions, e. g., for the subtraction function, recursive functions such as Euclidean division that are not structurally recursive in the strict sense are acceptable as strongly normalizing by the type system. While it may be a intellectually satisfying and understanding-heightening enterprise to exhibit deeper mathematical structures in generally recursive programs and turn them into primitive recursive ones, it is certainly desirable to have a type system that accepts as many terminating recursive programs as possible.

Altenkirch has suggested to me to represent type-based termination within dependent type theory, since sized types are in some sense “poor mans dependent types”. However, this would require the implementation of ordinal notation systems in type theory [CHS97], a non-trivial task. It seems impossible to implement the ordinal of F_{}in type theory, since it serves a the closure ordinal of all inductive definitions of the theory, hence, it should be inaccessible within the theory.

8.1.3 Sized Types

The work of Hughes, Pareto and Sabry [HPS96] and Pareto’s thesis [Par00], as well as the work of Giménez [Gim98], Frade [Fra03], and Barthe et al. [BFG^{+} 04], which are closest to this thesis, have already been related to our approach (e. g., see Section 1.5).

Barthe, Gregoire, and Pastawski [BGP05] have extended System F à la Church with sized inductive inductive types, arriving at System F . It is roughly the Church-version of with quantification over types. For this system they have implemented a type inference algorithm with computes and generalizes size constraints, and proven its soundness and completeness. Introducing dummy abstractions and applications to model type abstraction and application, F can be embedded into our calculus F_{}, which is in Curry-style, in a reduction preserving way. Data types in F_{}can be contravariant, interleaved, heterogeneous, and coinductive, which is not possible for data types in F .

Blanqui [Bla04, Bla05] decorates the inductive types of his Calculus of Algebraic Constructions, which is an extension of the Calculus of Inductive Constructions underlying Coq [BC04], with sizes of the same expressiveness as in F_{}and . He proves that reduction rules which adhere to the type-based termination criterion are strongly normalizing and presents a constraint-based algorithm for checking sized types. His system is quite powerful, featuring dependent types and reduction rules that go beyond computation ( ). However, our system is not subsumed since he does not feature size polymorphism or, since his positivity condition on data types is syntactical and not kind-based as in our approach, interesting heterogeneous data types.

Chin and Khoo [CK01], also with Xu [CKX01], extend the approach of Hughes, Pareto, and Sabry on sized types. They describe an algorithm how to infer lower and upper size bounds for a strict functional language with algebraic data types. Sizes are constrained by Presburger arithmetic formulas. They do not treat sizes that arise for data types with embedded function spaces.

Zenger [Zen98], introduces indexed types, which are a shallow form of dependent types, in the sense that they can express data invariants over decidable constraint domains, but cannot type more programs than a non-dependent language like Haskell. Zenger’s approach is similar to the one by Chin and Khoo. He cannot certify termination with his type system.

Portillo, Hammond, Loidl, and Vasconcelos [PHLV02] describe a cost inference algorithm for higher-order and polymorphic, but non-recursive functional programs. To estimated computation costs, they also need sized types. They treat the special case of sized natural numbers and sized lists, but their size language is more expressive than ours, featuring sum, difference, product, and maximum. Polymorphic combinators such as folds are problematic in their approach because all size information is lost. They could benefit from our idea to make size expressions first-class citizens in the type language, then list folds could be assigned a more precise type (see Section 1.5). Their approach has been extended to recursive functions by Vasconcelos and Hammond [VH04].

Rich size languages. Crary and Weirich [CW99] present a intermediate language, LX, for a typed compiler with a rich constructor level: Constructors form a strongly normalizing purely functional language on their own, with data structures and primitive recursion. Consequently, besides function kinds, they have product, sum, and inductive kinds, with a natural number kind as a special case. Data structures on the level of programs can be connected to their abstraction on the level of constructors, since recursive types can be parameterized by shapes, which are elements of inductive kinds. For example, a type of trees parameterized by a perfectly balanced constructor-level tree of size contains only perfectly balanced object-level trees of size . This way, structure invariants of data types can be represented in LX. To certify execution time bounds, the type system of LX is extended by a virtual clock [CW00]. The new language, LXres, can determine primitive-recursive execution costs, which are represented as constructors of kind Nat. To specify cost-functions, Crary and Weirich use a variant of Mendler-style primitive recursion (see Section 4.4) on the constructor level. It is not unthinkable to transfer our approach to terminating recursion to the constructor level of LXres. Our whole development would then occur one level higher; we would require sized inductive kinds, subkinding, and a sort of ordinals, sort then being the fourth syntactic level (objects, constructors, kinds, sorts).

Hongwei Xi [Xi02] presents a framework for type-based termination within DML, recently extended to ATS, which are a form of dependently typed programming languages, only that the program and type level expressions are syntactically separated (as in LX), but put into relation through singleton types. His sizes for types can be exact (as opposed to our system, where they are only upper bounds), and he allows termination on measures which are lexicographic products of natural numbers. He can treat many practical first- and higher-order functional programs. However, infinitely branching trees and coinductive structures are not covered by his approach.

150 CHAPTER 8. CONCLUSION

Appendix A

Summary of F_{}

In the following, we summarize the syntactic rules of F_{}.

A.1 Kinds and Constructors

Polarities. Order given by  and  .
::= +  covariant
contravariant
non-variant

Kinds. Pure kinds _{}do not mention ord.

::=  types
ord  ordinals
1  _{2}  co-/contra-/non-variant constructor transformers

Constructors are given by the following Curry-style type-level lambda-calculus with some constants.

::=

Signature. The constructor constants are taken from a fixed signature Σ which contains at least the following constants together with their kinding.

: ^{}^{+}  function space
: ( ^{}) ^{+}  quantification
: ord ^{+} ( _{}^{+} _{}) ^{+} _{}inductive constructors
: ord ^{}( _{}^{+} _{}) ^{+} _{}coinductive constructors
s : ord ^{+} ord  successor of ordinal
: ord  infinity ordinal

Polarized contexts.

Δ ::= Δ :

Operations on polarities and contexts. Negation of a polarity is given by the three equations (+ ) = , ( ) = + and ( ) = . We define inverse application ^{1} Δ of a polarity to a polarized context Δ.

+ ^{1} Δ  = Δ
1 ( )  =
1 (Δ : ) =  ^{1} Δ :( )
1 ( )  =
1 (Δ : ) = ^{1} Δ :
1 (Δ :+ ) = ^{1} Δ
1 (Δ : ) = ^{1} Δ

Kinding. Δ :

kind-c \frac{: Σ}{Δ :}  kind-var \frac{:  Δ  +}{Δ :}

kind-abs \frac{Δ :  : ^{}}{Δ  :  ^{}}kind-app \frac{Δ  :  ^{}^{1} Δ :}{Δ  : ^{}}

Constructor equality. Computation axioms.

eq- \frac{Δ :  : ^{}^{1} Δ :}{Δ ( ) = [ ] : ^{}}

eq- \frac{Δ  :  ^{}}{Δ (  ) = :  ^{}}

eq- \overline{Δ s = : ord}

Congruences.

eq-c \frac{: Σ}{Δ = :}  eq-var \frac{:  Δ  +}{Δ = :}

eq-app \frac{Δ  = ^{}:  ^{}^{1} Δ = ^{}:}{Δ  = ^{}^{}: ^{}}

eq- \frac{Δ :  = ^{}: ^{}}{Δ  = ^{}:  ^{}}

A.2. TERMS, TYPING AND REDUCTION 153 Symmetry and transitivity.

eq-sym \frac{Δ  = ^{}:}{Δ ^{}= :}
eq-trans \frac{Δ _{1} = _{2} :  Δ _{2} = _{3} :}{Δ _{1} = _{3} :}

Declarative Higher-Order Subtyping. Reflexivity, transitivity, antisymmetry.

leq-refl \frac{Δ  = ^{}:}{Δ  ^{}:}
leq-trans \frac{Δ _{1}  _{2} :  Δ _{2}  _{3} :}{Δ _{1}  _{3} :}
leq-antisym \frac{Δ  ^{}:  Δ ^{}:}{Δ  = ^{}:}

Abstraction and application.

leq- \frac{Δ :  ^{}: ^{}}{Δ  ^{}:  ^{}}
leq-app \frac{Δ  ^{}:  ^{}^{1} Δ :}{Δ  ^{}: ^{}}
leq-app+ \frac{Δ  : +  ^{}Δ  ^{}:}{Δ  ^{}: ^{}}
leq-app \frac{Δ  :  ^{}^{1} Δ ^{}:}{Δ  ^{}: ^{}}

Successor and infinity.

leq-s-r \frac{Δ : ord}{Δ  s : ord}  leq- \frac{Δ : ord}{Δ  : ord}

A.2 Terms, Typing and Reduction

Terms.

::=  fix_{}^{}fix_{}^{}

154 APPENDIX A. SUMMARY OF F_{}

A.2.1 Static Semantics

Typing contexts.

Γ ::=  Γ : Γ :

Wellformed contexts.

cxt-empty \overline{cxt} cxt-tyvar \frac{Γ cxt}{Γ : cxt} cxt-var \frac{Γ cxt  Γ  :}{Γ : cxt}

Typing. Γ : Lambda-calculus.

ty-var \frac{( : ) Γ  Γ cxt}{Γ  :}  ty-abs \frac{Γ :  :}{Γ  :}
ty-app \frac{Γ  :  Γ  :}{Γ  :}

Quantification.

ty-gen \frac{Γ :  :}{Γ  : _{}}FV( )  ty-inst \frac{Γ  : _{}Γ  :}{Γ  :}

Subsumption.

ty-sub \frac{Γ : Γ :}{Γ :}

Folding and unfolding for (co)inductive types ( ).

ty-fold \frac{Γ  : ( _{}) }{Γ  : _{}( + 1) }  ty-unfold \frac{Γ  : _{}( + 1) }{Γ  : ( _{}) }

Recursion ( = ) and corecursion ( = ).

ty-rec

Γ fix_{}^{}-adm Γ : ord Γ fix_{}^{}: ( :ord ( + 1))

A.2.2 Admissible Recursion Types

Notation for size index. We sometimes write the size index superscript, e. g., instead of , or ^{}instead of .

Natural transformations. For constructors : , let

: : _{1} _{}

Also, we abbreviate ( _{1} ) ( _{}) by .

Admissible types for recursion and corecursion.

Γ fix_{}^{}-adm :  Γ :ord  = ( ^{}) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ :+ ord : ^{}for some ^{}= ^{} Γ : ord _{}: ^{}for 1 and Γ _{}: ^{}_{}for 1

Γ fix_{}^{}-adm :  Γ :ord  = ( ^{}) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ : ord _{}: ^{}(all ) for some ^{}= ^{}and Γ _{}: ^{}_{}for 1

A.2.3 Dynamic Semantics

(Lazy) Values.

Val  ::=
fix_{}^{}where + 1

Evaluation frames.

(_) ::= _fix_{}^{}_{1}_

Reduction. ^{}

( )  _{}[ ]
fix_{}^{}_{1}  _{}(fix_{}^{}) _{1}  if = fix_{^{}}^{}^{}_{1 ^{}}
(fix_{}^{}_{1})  _{}( (fix_{}^{}) _{1}) if = fix_{^{}}^{}^{}_{1 ^{}}_

plus congruences for all term constructors.

A.3 Semi-Continuous Types for Recursion

Positive contexts.

Cxt^{+} Π ::=  Π :+ _{}

156 APPENDIX A. SUMMARY OF F_{} Derivation system for semi-continuity. Δ; Π ^{}: for Converting ordinary derivations.

cont-in \frac{Δ  :}{Δ : ord; Π ^{}:}  cont-co \frac{Δ :+ ord  :  +}{Δ : ord; Π ^{}:}
cont-contra  \frac{Δ : ord  :}{Δ : ord; Π ^{}:}

-calculus part.

cont-var \frac{:  Δ Π  +}{Δ; Π ^{}:}
cont-abs \frac{Δ : ; Π ^{}: ^{}}{Δ; Π ^{}: ^{}}=

cont-app

Δ : ^{}ord; Π ^{}: ^{}^{1} Δ :

Δ : ^{}ord; Π ^{}: ^{}

Built-in constructors:

cont-sum \frac{Δ; Π ^{}:}{Δ; Π ^{}+ :}  cont-prod \frac{Δ; Π ^{}:}{Δ; Π ^{}:}
cont-arr \frac{Δ; ^{}:  Δ; Π ^{}:}{Δ; Π ^{}:}
cont- \frac{Δ; Π ^{}:}{Δ; Π ^{}_{}:}
cont-mu \frac{Δ; Π :+ _{}^{}: _{}Δ ^{}: ord}{Δ; Π ^{}^{}: _{}}
cont-nu \frac{Δ; Π :+ _{}^{}: _{}Δ ord}{Δ; Π ^{}^{}: _{}}

Improved criterion for admissible types.

Γ fix_{}^{}-adm iff Γ : ord  = ( _{1} ^{}) :
and Γ : ord; ^{}_{1} ^{}:
Γ fix_{}^{}-adm iff Γ : ord  = ( _{1} ^{}) :
and Γ : ord; ^{}_{1} ^{}:

Appendix B

Iso-Coinductive Constructors

In this section, we present a variant of F_{}which still has equi-inductive constructors, but iso-coinductive constructors, i. e., folding and unfolding coinductive types is no longer silent on the term level. It is clear that the iso-version of a system is strongly normalizing if the equi-version is (see Section 4.1). However, the normalization proof is easier: it can be carried out with the original, more constructive definition of saturated term sets. The main advantage is that saturated sets in the original sense are closed under unions. Of course, now the symmetry between induction and coinduction is somewhat broken. But this has also an advantage: The pathological neutral terms, recursive functions applied to corecursive values, disappear. Now, every neutral term is bound to have a free variable, so no closed term will get stuck.

In the following, we summarize the changes to system definition and soundness proof.

B.1 Syntax

Terms. We extend the language of terms by two new constants:

Const  ::= in^{}codata constructor
out^{}codata destructor

Typing. The folding and unfolding rules are replaced by the following:

ty-fold^{}\frac{Γ  : ( _{}) }{Γ  : _{}( + 1) }  ty-unfold^{}\frac{Γ  : _{}( + 1) }{Γ  : ( _{}) }

ty-fold^{}\frac{Γ  : ( _{}) }{Γ in^{}: _{}( + 1) }  ty-unfold^{}\frac{Γ  : _{}( + 1) }{Γ out^{}: ( _{}) }

The rules for -terms, quantification, subsumption, recursion and corecursion stay in place.

Example B.1 (Repeat function, revisited) In the new system, the body of repeat is wrapped into a codata constructor.

repeat := fix_{0}^{}repeat in^{}(pair repeat)
repeat :  Stream^{}

Evaluation frames. The codata destructor is a new atomic evaluation context:

Eframe  ::= _application
fix_{}^{}_{1}_recursive function call
out^{}_codata destruction

Evaluation context are compositions of evaluation frames, as before.

Values. The new constants give rise to new values. As before, each underapplied constant is a value, but also codata construction in^{}.

Val  ::=
fix_{}^{}
fix_{}^{}where 0
out^{}in^{}in^{}

Reduction. Corecursive functions are only unrolled under a codata destructor. We get the following contractions:

red-  ( )  ↣ [ ]
red-rec  fix_{}^{}_{1}  ↣ (fix_{}^{}) _{1}
red-corec  out^{}(fix_{}^{}_{1}) ↣ out^{}( (fix_{}^{}) _{1})
red- _{}out^{}(in^{})  ↣

By requiring explicit folding and unfolding for codata, we have syntactically removed the critical application of recursive functions to corecursive values. The term fix_{}^{}_{1}(fix_{^{}}^{}^{}_{1 ^{}}) now has only one sensible reduction: unrolling recursion; corecursion requires a destructor to be unrolled.

Example B.2 (Reduction for repeat) The codata destructor triggers one unrolling and then vanishes with the freshly created codata constructor.

out^{}(repeat )  out^{}(( repeat in^{}(pair repeat)) (repeat ))
out^{}(in^{}(pair (repeat ))
pair (repeat )

B.2 Soundness

Safe evaluation contexts. Codata destruction is an additional safe evaluation context.

sf-out out^{}_Sframe Safe weak head reduction now also accounts for _{}-contractions.

req-  ( )  ▷ [ ]  if
req-rec  fix_{}^{}_{1}  ▷ (fix_{}^{}) _{1}
req-corec  out^{}(fix_{}^{}_{1}) ▷ out^{}( (fix_{}^{}) _{1})
req- _{}out^{}(in^{})  ▷
req-ecxt  ( ) ▷ ( ^{})  if ▷ ^{}
req-trans  ▷ is transitive

The requirement

req-fix^{}fix^{}fix_{}^{}_{1}(fix_{^{}}^{}^{}_{1 ^{}}^{}) if ^{}{ \atop ^{}}

can be dropped, since req-rec now covers also the application of a recursive function to a corecursive value.

We still require

req-fix^{}fix_{}^{}^{+1}

Saturated sets. We revert to our old definition: A set is saturated, SAT, if and is closed under ▷-reduction and -expansion.

Lemma B.3 If is saturated, then also ^{}:= out^{}.

Proof. To show  ^{}, we require out^{}( ) . Since  , by assump-

tion, we conclude with req-strict . The next goal, ^{}follows from the new requirement

req-out^{}out^{}implies

Finally, we need to show that ^{}is closed under ▷-reduction and -expansion. This property is inherited from by req-ecxt . □

Lattice of saturated sets. SAT forms a complete lattice under the set-theoretic intersection and union. That we now have sup 𝔄 = 𝔄 = 𝔄 for 𝔄 SAT, is the main gain of this development.

Lemma B.4 Let 𝔄 SAT. Then 𝔄 SAT and 𝔄 SAT.

Proof. If 𝔄 is empty, then 𝔄 = and 𝔄 = . Otherwise, let 𝔄.

Then there exists some  𝔄 such that  . Now if ▷ ^{}or ◁ ^{}, then
𝔄, hence, 𝔄 is closed. If  𝔄 then  for all 𝔄. Since

all are closed, each ▷-reduction or -expansion ^{}of is in every , hence, also in 𝔄. □

Semantics of and . Let = and = .

out_{_{}}^{1}  : ([[ ]]^{+} [[ ]]) ^{+} [[ ]]^{+} [[ ]]
out_{_{}}^{1} ( )( )( ) :=  out^{}( )( )
Sem( _{})( )( )  := ^{}( ^{})
Sem( _{})( )( )  := (out_{_{}}^{1} ( ))^{}( ^{})

Since [[ ]] = SAT, we have [[ _{}]] = Sem( _{}) [[ord]] ^{}([[ ]] ^{+} [[ ]]) ^{+} [[ ]], hence, the semantics of coinductive types is sound.

Lemma B.5 (Soundness of codata construction) Let  SAT. If  then

in^{}out^{}.

Proof. out^{}(in^{}) ▷ , and is closed under ▷-expansion. □

Lemma B.6 (Soundness of (un)folding for coinductive constructors) Let = , _{}[[ _{}]] [[ ]]^{+} [[ ]], and [[ord]]. We set

:= ([[ _{}]] )( )  (unfolded)
:= ([[ _{}]]([[s]] ) )( )  (folded)

Then in^{}( ) and out^{}( ) .

Proof. If ^{ord}, then

= out_{_{}}^{1} ( )([[ _{}]] )( )

which means that out^{}. With Lemma B.5, our claim follows. In case = ^{ord} the equation for is still valid, since the fixed point is reached at the closure ordinal. □

The soundness of rules ty-fold^{}and ty-unfold^{}is a consequence of this theorem.

Admissible semantic types for corecursion. We need to prove soundness of corecursion again, now for our old definition of SAT. The reasoning power we have lost by reverting to the old definition of SAT is compensated by a new requirement adm- -step .

The semantic type family O SAT is admissible for corecursion with arguments if the following four conditions are met:

adm- -shape  ( ) = _{}( _{1}( ) ( ))

for some index set and _{1} O SAT

adm- -start  ( 0) for all
adm- -step ^{}( + 1) and out^{}▷ out^{}^{}imply ( + 1)
adm- -limit  inf_{}( ) ( ) for all limits 0 = O

Lemma B.7 (Corecursion is a function) Let O SAT be admissible for corecursion with arguments. If ( ) ( + 1) for all + 1 O, then fix_{}^{}( ) for all O.

Proof. By transfinite induction on O. The new proof differs from the old one in the step case.

The limit case is a direct consequence of adm- -limit .

For the remaining cases, using adm- -shape , assume , _{}_{}( ) for 1 and show := fix_{}^{}( ). Note that and _{}are safe, hence, by req-fix^{}. Since ( 0), we are done in case of = 0.

For case = + 1, we have (fix^{}) ( + 1) by induction hypothesis and assumption, hence, (fix^{}) ( + 1). Since out^{}▷ out^{}( (fix^{})),

by adm- -step it follows that  ( + 1).  □

Admissible types for corecursion, syntactically. We recapitulate the criterion on types for corecursion:

Γ fix_{}^{}-adm :  Γ :ord  = ( ( ^{}) ) : ( FV( ))

for some with = and

Γ  : +  for some pure =

Γ : ord _{}: ^{}(all ) for some ^{}= ^{}and Γ _{}: ^{}_{}for 1

Lemma B.8 (Soundness of admissible corecursion types)  If Γ  fix_{}^{}-adm

and [[Γ]], then [[ ]]_{}is admissible for corecursion with arguments.

Proof. As in proof of the corresponding lemma 3.46, we set

( ) = [[ ]]_{}( ) = [[ ( ^{}) ]]_{[ ]}

In the following, we verify the conditions adm- -shape and adm- -step ; adm- -start and adm- -limit are proven as before.

adm- -shape Show ( ) = _{}_{1}( ) ( ). We set

:= [[ _{1}^{}]]  [[ _{}^{}]]  where := ^{}
( ) := [[ _{}]]_{[ ]} for 1  and
:= out_{_{}}^{1} ([[ ]]_{})
( ) := [[ _{}]]_{}for 1
( ) := (I_{}^{})( ( ))

adm- -step Assume ^{}( + 1) = (I_{})( ( )) and out^{}▷ out^{}^{}. By assumption, out^{}^{}[[ ]]_{}(I_{})( ( )), and since this set is closed by ▷-expansion, out^{}inhabits it as well. But this means that ( + 1), as required. □

Theorem B.9 (Soundness of typing) If Γ : and [[Γ]]then ⦇ ⦈_{}[[ ]]_{}.

Proof. By induction on the typing derivation. We do the new cases. For inductive constructors, nothing changes; ty-fold^{}can be handled as ty-fold before, and the same holds for unfolding. The cases for coinductive constructors are:

Case

ty-fold^{}\frac{Γ  : ( _{}) }{Γ in^{}: _{}( + 1) }
By Lemma 3.5 we have Γ  ( _{}) : , which entails Γ  : +
and Γ  : ord, as well as Γ  _{}: _{}for 1  , if we define

:= . Hence, := [[ ]]_{}[[ ]] ^{+} [[ ]]and := [[ ]]_{}[[ord]]and we can conclude by Lemma B.6.

Case

ty-unfold^{}\frac{Γ  : _{}( + 1) }{Γ out^{}: ( _{}) }

Analogously to case ty-fold^{}.

□

B.3 Strong Normalization

Strong(-ly normalising) head reduction _{SN} ^{}is defined inductively by the following rules.

shr- \frac{SN}{( ) _{SN} [ ]}  shr-frame \frac{_{SN} ^{}}{( ) _{SN} ( ^{})}

shr-rec \overline{fix_{}^{}_{1}  _{SN} (fix_{}^{}) _{1}}

shr-corec

out^{}(fix_{}^{}_{1}) _{SN} out^{}( (fix_{}^{}) _{1})
shr- _{}\overline{out^{}(in^{}) _{SN}}

It is easy to see that _{SN} is deterministic and closed under evaluation contexts, hence we can set its reflexive-transitive extension _{SN}^{}to be ▷.

Strongly neutral terms SNe are defined inductively by the following rules. The pathological case sne-fix^{}fix^{}has disappeared.

sne-var \overline{SNe}  sne-frame \frac{SNe  Sframe}{( ) SNe}

Strongly normalizing terms SN. The last three rules account for the new constants.

sn-sne \frac{SNe}{SN}  sn-abs \frac{SN}{SN}  sn-fix \frac{SN}{fix_{}^{}SN} + 1

sn-exp \frac{_{SN} ^{}^{}SN}{SN} sn-roll \frac{(fix_{}^{}) SN}{fix_{}^{}SN}

sn-in \frac{SN}{in^{}SN}  sn-in \overline{in^{}SN}  sn-out \overline{out^{}SN}

(We have reused the rule name sn-in in the same sense as we have reused the name sn-fix .)

It is clear that SN is closed under ▷-expansion (rule sn-exp ) and -reduction (each head redex must have been introduced by sn-exp ). Hence, we can set = SN, and req- -closed is fulfilled. We also see that each term in SN strong head reduces either to a value or to a strongly neutral term. Setting = ^{▷}SNe, the requirement req- -val becomes true: each term reduces to a value, ▷ . Of course (req- -sub- ) and ( ) (req-strict ) are validated immediately as well. The requirement req-fix^{}is an instances of the rules sn-fix ; the requirement req-out^{}is fulfilled by the following lemma.

Lemma B.10 (req-out^{}) If :: out^{}SN then SN.

Proof. By induction on .

Case

sn-sne \frac{sne-frame \frac{SN}{out^{}SN}}{out^{}SN}

By assumption SN.

Case

sn-exp \frac{out^{}(fix_{}^{}_{1}) _{sn} out^{}( (fix_{}^{}) _{1}) SN}{out^{}(fix_{}^{}_{1}) SN}

By induction hypothesis, (fix_{}^{}) _{1} SN. Then by sn-roll , fix_{}^{}_{1} SN.

Case

sn-exp \frac{out^{}(in^{}) _{sn}  SN}{out^{}(in^{}) SN}

By sn-in , in^{}SN. □

164 APPENDIX B. ISO-COINDUCTIVE CONSTRUCTORS Proof of req-fun-safe SN SN. It is sufficient to show that SN implies SN.

The following lemma holds in the new setting since corecursion is no longer unrolled under application. Lemma B.11 If :: _{SN} then either = or = ^{}with _{SN} ^{}. Proof. By induction on . □

Lemma B.12 (Extensionality) If ::  SN or ::  SNe then SN.

Proof. By induction on . Case

sne-frame \frac{SNe}{SNe}

By sn-sne , SN. Case Let = .

sne-frame \frac{SN}{fix_{}^{}SNe}

By sn-fix , fix_{}^{}SN. Case

sn-sne \frac{SNe}{SN}

By induction hypothesis. Case

sn-fix \frac{SN}{fix_{}^{}SN}

Then fix_{}^{}SN by sn-fix . Case

sn-roll \frac{(fix_{}^{}) SN}{fix_{}^{}SN}

By induction hypothesis (fix_{}^{}) SN, hence, fix_{}^{}SN by sn-roll . Case

sn-roll \frac{(fix_{}^{}) SN}{fix_{}^{}SN}

Then fix_{}^{}SN by sn-fix .

Case

sn-exp \frac{_{SN}  SN}{SN}

By Lemma B.11, we can distinguish two cases. If = , then SN by sn-abs . Otherwise, = ^{}and _{SN} ^{}. By induction hypothesis, SN, hence, SN by sn-exp .

Case

sn-in \frac{SN}{in^{}SN}

By sn-in we have in^{}SN. □

Corollary B.13 (req-fun-safe ) SN SN.

Proof.  SN for all  SN SN by the lemma. □

Soundness for the inductive characterization, SN sn, can be proven as before.

166 APPENDIX B. ISO-COINDUCTIVE CONSTRUCTORS

Appendix C

Galois Connections

We follow Vouillon [Vou04]. Definition C.1 (Galois connection) Let ( _{}) and ( _{}) be partially ordered sets. A pair of functions ( ) ( ) ( ) is called a Galois connection between and iff

( ) _{}_{}( )

Lemma C.2 The pair ( ) is a Galois connection iff 1. is contractive, is extensive, and

2. and are isotone. Proof. 1. Since ( ) ( ), we have ( ( )) . Likewise, ( ( )) follows from ( ) ( ). 2. The assumption ^{}implies ( ( ^{}) since is extensive, hence ( ) ( ^{}). Isotonicity of is proven analogously.

For the converse direction, first assume ( ) . This entails ( ( )) ( ). The reverse implication is equally trivial. □ Corollary C.3

1. Both  = and  = .
2.  and  are idempotent.

Definition C.4 (Closure operator) A function \overline{}is a closure operator on ( ) if it is isotone, extensive, and idempotent. Corollary C.5 If ( ) is a Galois connection between and , then is a closure operator on .

Lemma C.6 (Polarity) Let be a relation and

( ) ( )
( ) := ^{}:=  for all
( ) ( )
( ) := ^{}:=  for all

Then ( ) is a Galois connection between ( ( ) ) and ( ( ) ), called the polarity.

Proof.

\begin{aligned}( ) & (  ) \\ & (  )  ( ) \end{aligned}
□

Example C.7 (Orthogonality) Consider a set of safe terms Tm. The orthogonality relation Tm Ecxt between terms and evaluation contexts is given by

( )

Then the function \overline{}:= ^{}is a closure operator on sets of terms, and for Ecxt the set of terms ^{}is closed.

Bibliography

[AA00] Andreas Abel and Thorsten Altenkirch. A predicative strong normalisation proof for a -calculus with interleaving inductive types. In T. Coquand, P. Dybjer, B. Nordström, and J. Smith, editors, Types for Proof and Programs, International Workshop, TYPES ’99, volume 1956 of Lecture Notes in Computer Science, pages 21–40. Springer-Verlag, 2000.

[AA02] Andreas Abel and Thorsten Altenkirch. A predicative analysis of structural recursion. Journal of Functional Programming, 12(1):1–41, January 2002.

[Abe98] Andreas Abel. foetus – termination checker for simple functional programs. Programming Lab Report, 1998.

[Abe99] Andreas Abel. A semantic analysis of structural recursion. Master’s thesis, Ludwig-Maximilians-University Munich, 1999.

[Abe00] Andreas Abel. Specification and verification of a formal system for structurally recursive functions. In Thierry Coquand, Peter Dybjer, Bengt Nordström, and Jan Smith, editors, Types for Proof and Programs, International Workshop, TYPES ’99, volume 1956 of Lecture Notes in Computer Science, pages 1–20. Springer-Verlag, 2000.

[Abe03] Andreas Abel. Termination and guardedness checking with continuous types. In M. Hofmann, editor, Typed Lambda Calculi and Applications (TLCA 2003), Valencia, Spain, volume 2701 of Lecture Notes in Computer Science, pages 1–15. Springer-Verlag, June 2003.

[Abe04] Andreas Abel. Termination checking with types. RAIRO – Theoretical Informatics and Applications, 38(4):277–319, 2004. Special Issue: Fixed Points in Computer Science (FICS’03).

[Abe05] Andreas Abel. Termination and productivity checking with continuous types—second thoughts. http://www.tcs.ifi.lmu.de/˜ abel/errata-tlca03.pdf, January 2005.

[AC05] Andreas Abel and Thierry Coquand. Untyped algorithmic equality for Martin-Löf’s logical framework with surjective pairs. In Paweł Urzyczyn, editor, Typed Lambda Calculi and Applications (TLCA 2005), Nara, Japan, volume 3461 of Lecture Notes in Computer Science, pages 23–38. Springer-Verlag, April 2005.

[ACG98] Roberto M. Amadio and Solange Coupet-Grimal. Analysis of a guard condition in type theory. In Maurice Nivat, editor, Foundations of Software Science and Computation Structures, First International Conference, FoSSaCS’98, volume 1378 of Lecture Notes in Computer Science, pages 48–62. Springer-Verlag, 1998.

[AG00] Thomas Arts and Jürgen Giesl. Termination of term rewriting using dependency pairs. Theoretical Computer Science, 236:133–178, 2000.

[AJ05] Klaus Aehlig and Felix Joachimski. Continuous normalization for the lambda-calculus and Gödel’s T. Annals of Pure and Applied Logic, 133:39–71, 2005.

[Alt93] Thorsten Altenkirch. Constructions, Inductive Types and Strong Normalization. PhD thesis, University of Edinburgh, November 1993.

[Alt99] Thorsten Altenkirch. Logical relations and inductive/coinductive types. In G. Gottlob, E. Grandjean, and K. Seyr, editors, Computer Science Logic, 12th International Workshop, CSL ’98, Annual Conference of the EACSL, Brno, Czech Republic, August 24-28, 1998, Proceedings, Lecture Notes in Computer Science, pages 343–354. Springer-Verlag, 1999.

[Alt01] Thorsten Altenkirch. Representations of first order function types as terminal coalgebras. In Typed Lambda Calculi and Applications, TLCA 2001, number 2044 in Lecture Notes in Computer Science, pages 8 – 21. Springer-Verlag, 2001.

[AM03] Andreas Abel and Ralph Matthes. (Co-)iteration for higher-order nested datatypes. In H. Geuvers and F. Wiedijk, editors, Types for Proofs and Programs, International Workshop, TYPES 2002, volume 2646 of Lecture Notes in Computer Science, pages 1–20, Berg en Dal, The Netherlands, 2003. Springer-Verlag.

[AM04] Andreas Abel and Ralph Matthes. Fixed points of type constructors and primitive recursion. In Jerzy Marcinkowski and Andrzej Tarlecki, editors, Computer Science Logic, CSL’04, volume 3210 of Lecture Notes in Computer Science, pages 190–204. Springer-Verlag, 2004.

[AMM05] Thorsten Altenkirch, Conor McBride, and James McKinna. Why dependent types matter. Manuscript, available online, April 2005.

[AMU03] Andreas Abel, Ralph Matthes, and Tarmo Uustalu. Generalized iteration and coiteration for higher-order nested datatypes. In A. Gordon, editor, Foundations of Software Science and Computation Structures (FoSSaCS 2003), volume 2620 of Lecture Notes in Computer Science, pages 54–69, Warsaw, Poland, April 2003. Springer-Verlag.

[AMU05] Andreas Abel, Ralph Matthes, and Tarmo Uustalu. Iteration schemes for higher-order and nested datatypes. Theoretical Computer Science, 333(1–2):3–66, 2005.

[AR99] Thorsten Altenkirch and Bernhard Reus. Monadic presentations of lambda terms using generalized inductive types. In Jörg Flum and Mario Rodríguez-Artalejo, editors, Computer Science Logic, 13th International Workshop, CSL ’99, 8th Annual Conference of the EACSL, Madrid, Spain, September 20-25, 1999, Proceedings, volume 1683 of Lecture Notes in Computer Science, pages 453–468. Springer-Verlag, 1999.

[Bar99] Bruno Barras. Auto-validation d’un sysème de preuves avec familles inductives. PhD thesis, Universit’e Paris 7, 1999.

[BB85] Corrado Böhm and Alessandro Berarducci. Automatic synthesis of typed -programs on term algebras. Theoretical Computer Science, 39:135–154, 1985.

[BB00] Antonia Balaa and Yves Bertot. Fix-point equations for wellfounded recursion in type theory. In Mark Aagaard and John Harrison, editors, Theorem Proving in Higher Order Logics, 13th International Conference, TPHOLs 2000, Portland, Oregon, USA, August 14-18, 2000, Proceedings, volume 1869 of Lecture Notes in Computer Science, pages 1–16. Springer-Verlag, 2000.

[BC04] Yves Bertot and Pierre Castéran. Interactive Theorem Proving and Program Development. Coq’Art: The Calculus of Inductive Constructions. Texts in Theoretical Computer Science. An EATCS Series. Springer-Verlag, Berlin, May 2004.

[BC05a] Ana Bove and Venanzio Capretta. Modelling general recursion in type theory. Mathematical Structures in Computer Science, 15(4):671– 708, 2005.

[BC05b] Ana Bove and Venanzio Capretta. Recursive functions with higher order domains. In Pawel Urzyczyn, editor, Typed Lambda Calculi and Applications (TLCA 2005), Nara, Japan, volume 3461 of Lecture Notes in Computer Science, pages 116–130. Springer-Verlag, 2005.

[Bee04] Michael Beeson. Lambda logic. In D. Basin and M. Rusinowitch, editors, Automated Reasoning, 2nd International Joint Conference, IJ-CAR 2004, volume 3097 of Lecture Notes in Artificial Intelligence, pages 440–474, Cork, Ireland, July 2004. Springer-Verlag.

[Ber05] Yves Bertot. Filters on coinductive streams, an application to eratosthenes’ sieve. In Pawel Urzyczyn, editor, Typed Lambda Calculi and Applications (TLCA 2005), Nara, Japan, volume 3461 of Lecture Notes in Computer Science, pages 102–115. Springer-Verlag, 2005.

[BFG^{+} 04] G. Barthe, M. J. Frade, E. Giménez, L. Pinto, and T. Uustalu. Typebased termination of recursive definitions. Mathematical Structures in Computer Science, 14(1):1–45, 2004.

[BGJ00] Richard Bird, Jeremy Gibbons, and Geraint Jones. Program optimisation, naturally. In Millenial Perspectives in Computer Science, Palgrave, 2000.

[BGP05] Gilles Barthe, Benjamin Grégoire, and Fernando Pastawski. Practical inference for type-based termination in a polymorphic setting. In Pawel Urzyczyn, editor, Typed Lambda Calculi and Applications (TLCA 2005), Nara, Japan, volume 3461 of Lecture Notes in Computer Science, pages 71–85. Springer-Verlag, 2005.

[BJO01] Frédéric Blanqui, Jean-Pierre Jouannaud, and Mitsuhiro Okada. Inductive data type systems. Theoretical Computer Science, 277, 2001.

[Bla04]  Frédéric Blanqui.  A type-based termination criterion for

dependently-typed higher-order rewrite systems. In Vincent van Oostrom, editor, Rewriting Techniques and Applications, 15th International Conference, RTA 2004, Aachen, Germany, June 3 – 5, 2004, Proceedings, volume 3091 of Lecture Notes in Computer Science, pages 24–39. Springer-Verlag, 2004.

[Bla05] Frédéric Blanqui. Decidability of type-checking in the Calculus of Algebraic Constructions with size annotations. In C.-H. Luke Ong, editor, Computer Science Logic, 19th International Workshop, CSL 2005, 14th Annual Conference of the EACSL, Oxford, UK, August 22-25, 2005, Proceedings, volume 3634 of Lecture Notes in Computer Science, pages 135–150. Springer-Verlag, 2005.

[BM98] Richard Bird and Lambert Meertens. Nested datatypes. In Johan Jeuring, editor, Mathematics of Program Construction, MPC’98, Proceedings, volume 1422 of Lecture Notes in Computer Science, pages 52–67. Springer-Verlag, 1998.

[BP99a] Richard Bird and Ross Paterson. Generalised folds for nested datatypes. Formal Aspects of Computing, 11(2):200–222, 1999.

[BP99b] Richard S. Bird and Ross Paterson. De Bruijn notation as a nested datatype. Journal of Functional Programming, 9(1):77–91, 1999.

[Buc91] Wilfried Buchholz. Notation systems for infinite derivations. Archive of Mathematical Logic, 30:277–296, 1991.

[Buc05] Wilfried Buchholz. A term calculus for (co-)recursive definitions on streamlike data-structures. Annals of Pure and Applied Logic, 136(1–2):75–90, 2005.

[Bur69] Rod Burstall. Proving properties of programs by structural induction. Computer Journal, 12(1):41–48, 1969.

[Cap05] Venanzio Capretta. General recursion via coinductive types. Logical Methods in Computer Science, 2005. To appear.

[CC99] Catarina Coquand and Thierry Coquand. Structured type theory. In Workshop on Logical Frameworks and Meta-languages (LFM’99), Paris, France, September 1999.

[CHS97] Thierry Coquand, Peter Hancock, and Anton Setzer. Ordinals in type theory. Slides, August 1997. Aarhus.

[CK01] Wei-Ngan Chin and Siau-Cheng Khoo. Calculating sized types. Higher-Order and Symbolic Computation, 14(2–3):261–300, 2001.

[CKX01] Wei-Ngan Chin, Siau-Cheng Khoo, and Dana N. Xu. Higher-order polymorphic sized types for safety checks. In The Second Asian Workshop on Programming Languages and Systems, APLAS’01, Korea Advanced Institute of Science and Technology, Daejeon, Korea, December 17-18, 2001, Proceedings, pages 117–131, 2001.

[Coq92] Thierry Coquand. Pattern matching with dependent types. In Bengt Nordström, Kent Pettersson, and Gordon Plotkin, editors, Proceedings of the 1992 Workshop on Types for Proofs and Programs, Båstad, Sweden, June 1992, pages 71–83, 1992.

[Coq93] Thierry Coquand. Infinite objects in type theory. In H. Barendregt and T. Nipkow, editors, Types for Proofs and Programs (TYPES ’93), volume 806 of Lecture Notes in Computer Science, pages 62–78. Springer-Verlag, 1993.

[CW99] Karl Crary and Stephanie Weirich. Flexible type analysis. In Proceedings of the fourth ACM SIGPLAN International Conference on Functional Programming (ICFP ’99), Paris, France, volume 34 of SIG-PLAN Notices, pages 233–248. ACM Press, 1999.

[CW00] Karl Crary and Stephanie Weirich. Resource bound certification. In Proceedings of the 27th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, pages 184–198, Boston, Massachusetts, USA, January 2000.

[Dan99] Norman Danner. Transfinite iteration functionals and ordinal arithmetic. arXiv.org e-Print archive, August 1999.

[DC99] Dominic Duggan and Adriana Compagnoni. Subtyping for object type constructors, January 1999. Presented at FOOL 6.

[Dyb94] Peter Dybjer. Inductive families. Formal Aspects of Computing, 6(4):440–465, 1994.

[Far04] William M. Farmer. Formalizing undefinedness arising in calculus. In D. Basin and M. Rusinowitch, editors, Automated Reasoning, 2nd International Joint Conference, IJCAR 2004, volume 3097 of Lecture Notes in Artificial Intelligence, pages 475–489, Cork, Ireland, July 2004. Springer-Verlag.

[Fra03] Maria João Frade. Type-Based Termination of Recursive Definitions and Constructor Subtyping in Typed Lambda Calculi. PhD thesis, Universidade do Minho, Departamento de Informática, 2003.

[Geu92] Herman Geuvers. Inductive and coinductive types with iteration and recursion. In Bengt Nordström, Kent Pettersson, and Gordon Plotkin, editors, Proceedings of the 1992 Workshop on Types for Proofs and Programs, Båstad, Sweden, June 1992, pages 193–217, 1992.

[Gim95] Eduardo Giménez. Codifying guarded definitions with recursive schemes. In Peter Dybjer, Bengt Nordström, and Jan Smith, editors, Types for Proofs and Programs, International Workshop TYPES´ 94, Båstad, Sweden, June 6-10, 1994, Selected Papers, volume 996 of LNCS, pages 39–59. Springer, 1995.

[Gim98] Eduardo Giménez. Structural recursive definitions in type theory. In K. G. Larsen, S. Skyum, and G. Winskel, editors, Automata, Languages and Programming, 25th International Colloquium, ICALP’98, Aalborg, Denmark, July 13-17, 1998, Proceedings, volume 1443 of Lecture Notes in Computer Science, pages 397–408. Springer-Verlag, 1998.

[Gir72] Jean-Yves Girard. Interprétation fonctionnelle et élimination des coupures dans l’arithmétique d’ordre supérieur. Thèse de Doctorat d’État, Université de Paris VII, 1972.

[Gir01] Jean-Yves Girard. Locus solum: From the rules of logic to the logic of rules. Mathematical Structures in Computer Science, 11(3):301–506, 2001.

[GLT89] Jean-Yves Girard, Yves Lafont, and Paul Taylor. Proofs and Types, volume 7 of Cambridge Tracts in Theoretical Computer Science. Cambridge University Press, 1989.

[GM03] Pietro Di Gianantonio and Marino Miculan. A unifying approach to recursive and co-recursive definitions. In H. Geuvers and F. Wiedijk, editors, Types for Proofs and Programs, Second International Workshop, TYPES 2002, Berg en Dal, The Netherlands, April 24-28, 2002, Selected Papers, volume 2646 of Lecture Notes in Computer Science. Springer-Verlag, 2003.

[Gog94] Healfdene Goguen. A Typed Operational Semantics for Type Theory. PhD thesis, University of Edinburgh, August 1994. Available as LFCS Report ECS-LFCS-94-304.

[Gog95] Healfdene Goguen. Typed operational semantics. In M. Deziani-Ciancaglini and G. D. Plotkin, editors, Typed Lambda Calculi and Applications (TLCA 1995), volume 902 of Lecture Notes in Computer Science, pages 186–200. Springer-Verlag, 1995.

[Gog99] Healfdene Goguen. Soundness of the logical framework for its typed operational semantics. In Jean-Yves Girard, editor, Typed Lambda Calculi and Applications, TLCA 1999, volume 1581 of Lecture Notes in Computer Science, L’Aquila, Italy, 1999. Springer-Verlag.

[Hen93] Fritz Henglein. Type inference with polymorphic recursion. ACM Transactions on Programming Languages and Systems (TOPLAS), 15(2):253–289, 1993.

[Hin98] Ralf Hinze. Numerical representations as higher-order nested datatypes. Technical Report IAI-TR-98-12, Institut für Informatik III, Universität Bonn, December 1998.

[Hin99] Ralf Hinze. Polytypic functions over nested datatypes. Discrete Mathematics & Theoretical Computer Science, 3(4):193–214, 1999.

[Hin00a] Ralf Hinze. Efficient generalized folds. In Johan Jeuring, editor, Proceedings of the Second Workshop on Generic Programming, WGP 2000, Ponte de Lima, Portugal, July 2000.

[Hin00b] Ralf Hinze. Generalizing generalized tries. Journal of Functional Programming, 10(4):327–351, July 2000.

[Hin01] Ralf Hinze. Manufacturing datatypes. Journal of Functional Programming, 11(5):493–524, 2001.

[Hin02] Ralf Hinze. Polytypic values possess polykinded types. MPC Special Issue, Science of Computer Programming, 43:129–159, 2002.

[HJL04] Ralf Hinze, Johan Jeuring, and Andres Löh. Type-indexed data types. MPC Special Issue, Science of Computer Programming, 51:117– 151, 2004.

[HPS96] John Hughes, Lars Pareto, and Amr Sabry. Proving the correctness of reactive systems using sized types. In 23rd Symposium on Principles of Programming Languages, POPL’96, pages 410–423, 1996.

[Huf52] D. Huffman. My famous paper on Huffman trees. In Proc. IRE, volume 40, pages 1098–1101, 1952.

[Hut92] Dieter Hutter. Automatisierung der vollständigen Induktion. Oldenbourgh Verlag, 1992.

[JB04] Neil Jones and Nina Bohr. Termination analysis of the untyped -calculus. In Vincent van Oostrom, editor, Rewriting Techniques and Applications, 15th International Conference, RTA 2004, Aachen, Germany, June 3 – 5, 2004, Proceedings, volume 3091 of Lecture Notes in Computer Science, pages 1–23. Springer-Verlag, 2004.

[JG02] Neil D. Jones and Arne J. Glenstrup. Abstract and conclusions of PLI invited paper: program generation, termination, and bindingtime analysis. In Proceedings of the 4th ACM SIGPLAN International Conference on Principles and Practice of Declarative Programming, pages 1–1. ACM Press, 2002.

[JJ97] Patrik Jansson and Johan Jeuring. PolyP—a polytypic programming extension. In 24th Symposium on Principles of Programming Languages, POPL’97, Paris, France, pages 470–482. ACM Press, 1997.

[JM03] Felix Joachimski and Ralph Matthes. Short proofs of normalization. Archive of Mathematical Logic, 42(1):59–87, 2003.

[KTU93] Assaf Kfoury, Jerzy Tiuryn, and Paweł Urzyczyn. Type reconstruction in the presence of polymorphic recursion. ACM Transactions on Programming Languages and Systems (TOPLAS), 15(2):290–311, 1993.

[Lee02] Chin Soon Lee. Program termination analysis in polynomial time. In Don S. Batory, Charles Consel, and Walid Taha, editors, Generative Programming and Component Engineering, ACM SIGPLAN/SIGSOFT Conference, GPCE 2002, Pittsburgh, PA, USA, October 6-8, 2002, Proceedings, volume 2487 of Lecture Notes in Computer Science, pages 218–235. Springer-Verlag, 2002.

[LJBA01] Chin Soon Lee, Neil D. Jones, and Amir M. Ben-Amram. The sizechange principle for program termination. In ACM Symposium on Principles of Programming Languages (POPL’01), London, UK, January 2001. ACM Press.

[LS05] Sam Lindley and Ian Stark. Reducibility and -lifting for computation types. In Paweł Urzyczyn, editor, Typed Lambda Calculi and Applications (TLCA 2005), Nara, Japan, volume 3461 of Lecture Notes in Computer Science. Springer-Verlag, 2005.

[Luo90] Zhaohui Luo. ECC: An Extended Calculus of Constructions. PhD thesis, University of Edinburgh, 1990.

[Mat98] Ralph Matthes. Extensions of System F by Iteration and Primitive Recursion on Monotone Inductive Types. PhD thesis, Ludwig-Maximilians-University, May 1998.

[Mat99] John Matthews. Recursive function definition over coinductive types. In Yves Bertot, Gilles Dowek, André Hirschowitz, C. Paulin, and Laurent Théry, editors, Theorem Proving in Higher Order Logics, 12th International Conference, TPHOLs ’99, Nice, France, volume 1690 of Lecture Notes in Computer Science, pages 73–90. Springer-Verlag, 1999.

[Mat00] Ralph Matthes. Characterizing strongly normalizing terms of a calculus with generalized applications via intersection types. In ITRS 00, ICALP Satellite Workshops 2000, pages 339–354, 2000.

[Mat01] Ralph Matthes. Monotone inductive and coinductive constructors of rank 2. In Laurent Fribourg, editor, Computer Science Logic, 15th International Workshop, CSL 2001. 10th Annual Conference of the EACSL, Paris, France, September 10-13, 2001, Proceedings, volume 2142 of Lecture Notes in Computer Science, pages 600–614. Springer-Verlag, 2001.

[Mat05] Ralph Matthes. Non-strictly positive fixed-points for classical natural deduction. APAL, 2005. To appear.

[McB06] Conor McBride. Type-preserving renaming and substitution. Journal of Functional Programming, 2006. Functional Pearl. To appear.

[Men87] Nax P. Mendler. Recursive types and type constraints in secondorder lambda calculus. In Proceedings of the Second Annual IEEE Symposium on Logic in Computer Science, Ithaca, N.Y., pages 30–36. IEEE Computer Society Press, 1987.

[Men91] Nax Paul Mendler. Inductive types and type constraints in the second-order lambda calculus. Annals of Pure and Applied Logic, 51(1–2):159–172, 1991.

[MG01] Clare Martin and Jeremy Gibbons. On the semantics of nested datatypes. Information Processing Letters, 80(5):233–238, December 2001.

[MGB04] Clare Martin, Jeremy Gibbons, and Ian Bayley. Disciplined, efficient, generalised folds for nested datatypes. Formal Aspects of Computing, 16(1):19–35, 2004.

[Min78] Grigori Mints. Finite investigations of transfinite derivations. Journal of Soviet Mathematics, 10:548–596, 1978. Translated from: Zap. Nauchn. Semin. LOMI 49 (1975).

[MM04] Connor McBride and James McKinna. The view from the left. Journal of Functional Programming, 2004.

[Nor88] Bengt Nordström. Terminating general recursion. BIT, 28(3):605– 619, 1988.

[ORS92] S. Owre, J. M. Rushby, and N. Shankar. PVS: A prototype verification system. In Deepak Kapur, editor, 11th International Conference on Automated Deduction (CADE), volume 607 of Lecture Notes in Artificial Intelligence, pages 748–752, Saratoga, NY, June 1992. Springer-Verlag.

[Par97] Michel Parigot. Proofs of strong normalization for second order classical natural deduction. Journal of Symbolic Logic, 62(4):1461– 1479, 1997.

[Par00] Lars Pareto. Types for Crash Prevention. PhD thesis, Chalmers University of Technology, 2000.

[Pau90] Lawrence Paulson. Isabelle: The next 700 theorem provers. In P. Odifreddi, editor, Logic and Computer Science, pages 361–386. Academic Press, 1990.

[PDM89] Benjamin Pierce, Scott Dietzen, and Spiro Michaylov. Programming in higher-order typed lambda-calculi. Technical report, Carnegie Mellon University, 1989.

[PHLV02] A.J. Rebon Portillo, K. Hammond, H-W. Loidl, and P. Vasconcelos. Cost analysis using automatic size and time inference. In IFL’02 International Workshop on the Implementation of Functional Languages Madrid, Spain, September 16-18, 2002, volume 2670 of Lecture Notes in Computer Science, pages 232–247. Springer-Verlag, 2002.

[Pie01] Brigitte Pientka. Termination and reduction checking for higherorder logic programs. In Rajeev Goré, Alexander Leitsch, and Tobias Nipkow, editors, Automated Reasoning, First International Joint Conference, IJCAR 2001, volume 2083 of Lecture Notes in Artificial Intelligence, pages 401–415. Springer-Verlag, 2001.

[Pie02] Benjamin C. Pierce. Types and Programming Languages. MIT Press, 2002.

[PL89] Frank Pfenning and Peter Lee. LEAP: A language with eval and polymorphism. In TAPSOFT, Vol.2, volume 352 of Lecture Notes in Computer Science, pages 345–359. Springer-Verlag, 1989.

[Pol94] Randy Pollack. The Theory of LEGO. PhD thesis, University of Edinburgh, 1994.

[PS97] Benjamin C. Pierce and Martin Steffen. Higher order subtyping. Theoretical Computer Science, 176(1,2):235–282, 1997.

[PS99] Frank Pfenning and Carsten Schürmann. System description: Twelf - a meta-logical framework for deductive systems. In H. Ganzinger, editor, Proceedings of the 16th International Conference on Automated Deduction (CADE-16), volume 1632 of Lecture Notes in Artificial Intelligence, pages 202–206, Trento, Italy, July 1999. Springer-Verlag.

[RP93] J. C. Reynolds and G. D. Plotkin. On functors expressible in the polymorphic typed lambda calculus. Information and Computation, 105:1–29, 1993.

[Ruc85] Martin Ruckert. Church-Rosser Theorem und Normalisierung für Termkalküle mit unendlichen Termen unter Einschluß permutativer Reduktionen. PhD thesis, Mathematisches Institut der LMU München, 1985.

[Sch98] Helmut Schwichtenberg. Finite notations for infinite terms. Annals of Pure and Applied Logic, 94(1-3):201–222, 1998.

[Ser04] Damien Sereni. Size-change termination for higher-order functional programs. Technical report, Oxford University Computing Laboratory, 2004.

[Ser05] Damien Sereni. Simply-typed -calculus and SCT. Unpublished note, 2005.

[SJ05] Damien Sereni and Neil D. Jones. Termination analysis of higherorder functional programs. In Kwangkeun Yi, editor, Programming Languages and Systems, Third Asian Symposium, APLAS 2005, Tsukuba, Japan, November 2-5, 2005, Proceedings, volume 3780 of Lecture Notes in Computer Science, pages 281–297. Springer-Verlag, 2005.

[Sli96] Konrad Slind. Function definition in higher order logic. In Proceedings of TPHOLs 96, volume 1125 of Lecture Notes in Computer Science. Springer-Verlag, 1996.

[Ste95] Joachim Steinbach. Simplification orderings: History of results. Fundamenta Informaticae, 24(1/2):47–87, 1995.

[Ste98] Martin Steffen. Polarized Higher-Order Subtyping. PhD thesis, Technische Fakultät, Universität Erlangen, 1998.

[SU99] Zdzisław Spławski and Paweł Urzyczyn. Type fixpoints: Iteration vs. recursion. In Proceedings of the fourth ACM SIGPLAN International Conference on Functional Programming (ICFP ’99), Paris, France, volume 34 of SIGPLAN Notices, pages 102–113. ACM Press, 1999.

[Tai75] William W. Tait. A realizability interpretation of the theory of species. In R. Parikh, editor, Logic Colloquium Boston 1971/72, volume 453 of Lecture Notes in Mathematics, pages 240–251. Springer-Verlag, 1975.

[Tar55] Alfred Tarski. A lattice-theoretical fixpoint theorem and its applications. Pacific Journal of Mathematics, 5:285–309, 1955.

[TT97] Alastair J. Telford and David A. Turner. Ensuring streams flow. In Algebraic Methodology and Software Technology (AMAST ’97), volume 1349 of Lecture Notes in Computer Science, pages 509–523. Springer-Verlag, 1997.

[TT00] Alastair J. Telford and David A. Turner. Ensuring termination in ESFP. Journal of Universal Computer Science, 6(4):474–488, April 2000. Proceedings of BCTCS 15 (1999).

[Tur95] David Turner. Elementary strong functional programming. In Programming Languages in Education, First International Symposium, volume 1022 of Lecture Notes in Computer Science. Springer-Verlag, 1995.

[UV99] Tarmo Uustalu and Varmo Vene. Mendler-style inductive types, categorically. Nordic J. of Computing, 6(3):343–361, 1999.

[Vau04] Lionel Vaux. A type system with implicit types. English version of his mémoire de maîtrise, June 2004.

[VH04] Pedro B. Vasconcelos and Kevin Hammond. Inferring cost equations for recursive, polymorphic and higher-order functional programs. In Philip W. Trinder, Greg Michaelson, and Ricardo Pena, editors, Implementation of Functional Languages, 15th International Workshop, IFL 2003, Edinburgh, UK, September 8-11, 2003, Revised Papers, volume 3145 of Lecture Notes in Computer Science, pages 86– 101. Springer-Verlag, 2004.

[VM04] Jérôme Vouillon and Paul-André Melliès. Semantic types: A fresh look at the ideal model for types. In Neil D. Jones and Xavier Leroy, editors, Proceedings of the 31st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL 2004, Venice, Italy, January 14-16, 2004, pages 52–63. ACM Press, 2004.

[Vou04] Jérôme Vouillon. Subtyping union types. In Jerzy Marcinkowski and Andrzej Tarlecki, editors, Computer Science Logic, CSL’04, volume 3210 of Lecture Notes in Computer Science, pages 415–429. Springer-Verlag, 2004.

[vRS95] Femke van Raamsdonk and Paula Severi. On normalisation. Technical Report CS-R9545, CWI, 1995.

[vRSSX99] Femke van Raamsdonk, Paula Severi, Morten Heine Sørensen, and Hongwei Xi. Perpetual reductions in lambda calculus. Information and Computation, 149(2):173–225, March 1999.

[Wah04] David Wahlstedt. Type theory with first-order data types and size-change termination. Licentiate Thesis, Chalmers University of Technology, September 2004.

[Wal92] Christoph Walther. Computing induction axioms. In International Conference on Logic Programming and Automated Reasoning – LPAR 92, volume 624 of Lecture Notes in Artificial Intelligence, St. Petersburg, 1992. Springer-Verlag.

[WCPW03] Kevin Watkins, Iliano Cervesato, Frank Pfenning, and David Walker. A concurrent logical framework I: Judgements and properties. Technical report, School of Computer Science, Carnegie Mellon University, Pittsburgh, 2003.

[Wei05]  Eric  W.  Weisstein.  Goldbach  conjecture.
From  MathWorld–A  Wolfram  Web  Resource.

http://mathworld.wolfram.com/GoldbachConjecture.html, 2005.

[Xi01] Hongwei Xi. Dependent types for program termination verification. In Proceedings of 16th IEEE Symposium on Logic in Computer Science, Boston, USA, June 2001.

[Xi02] Hongwei Xi. Dependent types for program termination verification. Journal of Higher-Order and Symbolic Computation, 15(1):91– 131, October 2002.

[Zen98] Christoph Zenger. Indizierte Typen. PhD thesis, Fakultät für Informatik der Universität Kalsruhe, 1998.

182 BIBLIOGRAPHY

Index

, 87 fix , 89 Λ_{}^{+} , 88

abstract interpretation, 147 accessibility, 144 addition, 41 admissible for corecursion, 40, 41,

68, 73, 93, 160 admissible for recursion, 40, 41, 65,

72, 93 antitone, 19 antitone iteration, 102 application of polarities to contexts,

25 approximation, 57 approximation stages, 14 ascending chain, 59

Banach’s fixed-point theorem, 145 base kinds, 21 -reduction of constructors, 35 biorthogonal, 67 breadth-first traversal, 117 Brouwer ordinals, 23 Burroni conatural numbers, 42

calculus for semi-continuity, 107 Calculus of Algebraic Constructions,

148 Calculus of Inductive Constructions,

144, 148 canonical form, 43 cardinal, 59 Cartesian product, 22, 107 case distinction, 38 Church-style constructors, 32 closed, 61, 64, 67 closure operator, 71, 167 closure ordinal, 13, 59, 60, 147 codata constructor, 157 codata destructor, 157 coinduction, 121 coinductive, 22, 101 complete lattice, 31 confluent, 44 constructor, 19, 21 constructor equality, 27 context, 24 continuation passing, 37 continuous, 57 continuous normalization, 121 contraction, 43 contractive, 145 contravariant, 19 converging equivalence relations, 146 Coq, 144, 148 corecursion, 37, 39, 68, 147, 160 cost inference, 148 covariant, 19 Curry-Howard isomorphism, 9, 144 Curry-style -calculus, 37

data constructor, 86 de Bruijn term, 121, 124 de Morgan laws, 69 defuse, 52, 147 denotation of terms, 74 denotation of types, 33 derivation-independence of seman-

tics, 36 descending chain, 59 disjoint sum, 22, 107 diverging, 62 division, 41 domain, 24 domain predicate, 145 domain-free constructors, 32

elimination based, 62 embedding, 85 Epigram, 147 equi-coinductive, 16, 143 equi-inductive, 16, 157 equi-recursive, 16, 77, 85 equivalence relations, 145 evaluation context, 43 evaluation frame, 43 evaluation relation, 64 evaluator, 121 existential type, 22

Fibonacci numbers, 46 finite observations, 71 finitely branching tree, 110 fixed point, 59 fixed-point unfolding, 45

foetus, 146

folding, 39, 157 fuel, 145 function space, 22, 30, 62, 67, 99

Galois connection, 25, 71, 167 general recursion, 12 generalization, 39, 70 greatest fixed point, 59 guard condition, 89 guarded by constructors, 121 guarded by destructors, 88 guarded corecursion, 121 guarded, syntactically, 89

Halteproblem, 7 Haskell, 117 head, 43 height, 23 heterogeneous data types, 16, 23 higher-order functions, 11 Higher-Order Logic, 144 higher-order subtyping, 28 Huffman codes, 47

impredicative encodings, 22, 40, 143 impredicative polymorphism, 11 inaccessible, 147 indexed types, 148 induction scheme, 144, 145 inductive, 22 inductive characterization of strongly normalizing terms, 77

inductive kind, 149 inductive type, 13, 103 infimum, 30, 56 infimum continuous, 104 infinite height, 23 infinite ordinal, 15 infinite term, 121 infinitely branching, 11, 15, 144, 149 infinity ordinal, 22 inflationary, 58 information order, 20 instantiation, 39, 70 interpretation of kinds, 30 intersection, 30, 100, 159 introduction based, 62 intuitionistic negation, 69 inverse application of polarities, 25 Isabelle, 144 iso-coinductive, 157 iso-inductive, 16 iso-recursive, 16, 85 isotone, 19 isotone iteration, 103 iterate, 13, 57 iteration, 89

kind, 20

kind interpretation, 30 kind semantics, 30 kinding, 24, 26 Knaster, 59

labeled sum, 16 lambda dropping, 61 lambda-calculus, 39 lattice, 69, 159 least fixed point, 59 lenient, 104 lexicographic termination orderings,

146 liberal, 25 lim inf-pullable, 98 lim sup-pushable, 98 limes inferior, 56 limes superior, 56 limit, 56, 95 list, 23 list map, 41 list splitting, 41 list zip-with, 41 locally confluent, 44 lower semi-continuous, 96

Martin-Löf Type Theory, 144 maximal element, 30, 31 maximum, 41 measure, 144 Mendler-style recursion, 90 minimum, 41, 109, 140 mixed recursion-corecursion, 48, 145,

146 model, 61 modulus, 145 monotonicity, 19 multiplication, 41 mutual recursion, 137

natural transformation, 40, 72 negative occurrence, 24 nested data types, 16, 23 nested recursion, 137 neutral corecursive values, 68 neutral terms, 61, 162 non size-increasing, 11 non-strictly positive, 89 non-variant, 19 normal form, 43 normalization, 123 normalizer, 121

-overshooting, 97, 115 -undershooting, 97, 115 one-step reduction, 44 operator iteration, 57 ordered families of equivalences, 146 ordinal expressions, 21 ordinal iteration, 13 ordinal notation, 11, 147 ordinal variables, 21 ordinals, 21 orthogonal, 66 orthogonality, 66, 168 overshooting, 96, 115

pair, 38 paracontinuous, 97 parallel substitution, 124 Partial evaluation, 9 partial order, 31 partiality, 9, 135 partially ordered set, 30 pattern matching, 117, 140 pointwise infimum, 31 pointwise supremum, 31 polarity, 19, 107 polarity composition, 20 polarized context, 24 polarized inclusion, 30 poset, 30 positive occurrence, 24 positive context, 108 positivity condition, 24, 89, 148 power lists, 23 prime numbers, 50 primitive recursion, 89, 147 product type, 22, 107 program analysis, 143 projection, 38 pullable, 98 pulled through, 98 Pure kinds, 21 pushable, 98 pushes through, 97 PVS, 144

quantification, 22, 39, 100

rank, 21 rank-2 polymorphism, 11 recursion, 37, 39, 65 recursion, Mendler-style, 90 recursive argument, 42 reducibility candidates, 62 reduction, 43 reduction preserving embedding, 85 reflexivity, 28 regular data types, 23 repeat, 41 requirements, 65, 68 rose tree, 117

Safe, 61 safe evaluation context, 63 safe terms, 61 safe weak head reduction, 64, 159 saturated, 62, 64, 94, 157, 159 saturation, 66, 143 semantical type, 62 semantics of constructors, 32 semantics of kinding derivations, 33 semantics of kinds, 30 semantics of types, 32 semi-continuity, 95, 96, 143 semi-continuous types, 15 Sieve of Eratosthenes, 145 signature, 22 singular, 74 size-change principle, 146 size-change termination, 146 sized inductive type, 13 sized types, 23 soundness, 36, 61, 110, 162 stage expressions, 22 stream, 109 stream filtering, 145 strict, 63 strictly positive, 89, 108 strong head reduction, 78, 162 strong normalization, 61, 162 strong normalization, inductive char-

acterization, 77 strongly neutral terms, 78, 162 strongly normalizing terms, 79, 163 subject reduction, 35, 77 substitution, 123 subsumption, 39 subtraction, 41 subtyping, 28 successor of ordinal, 22 sum type, 22, 107 supremum, 30, 56, 70, 94, 101, 159 Synchronous Haskell, 15, 88 syntactic guardedness, 89 systems with partiality, 9

Tarski, 59 term, 37 term model, 61 termination, 7 termination checking, 144 termination conditions, 144 termination proof, 144 top element, 31 total correctness, 9 total systems, 9 transfinite induction, 95 transfinite iteration, 57 tree, 23 type constructor, 19 type equality, 27 type interpretation, 33 type interval, 62 type preservation, 77 type preserving embedding, 85 type transformer, 19 type variable, 90 type-based termination, 10, 12 typed intermediate language, 149 types paradigm, 143 typing context, 38 typing derivation, 11

ultrametric space, 145 uncountable, 15, 59 undershooting, 97, 115 unfolding, 39, 157 union, 30, 70, 94, 157, 159 universal quantification, 100 upper semi-continuous, 96

validity, 28, 29 valuation, 32, 74 value, 43 variance, 19

weak head reduction, 64 well-formed context, 38 well-founded recursion, 144