Types and Programming Languages. Lecture 8. Recursive type

Similar documents
Chapter 21: Metatheory of Recursive Types. Induction and Coinduction Finite and Infinite Types/Subtyping Membership Checking

ADT. Typing. Recursive Types. Java. Preliminary: syntax, operational semantics. Untyped lambda calculus. Simply typed lambda calculus

Lecture 14: Recursive Types

Derivation for the Necessity of Recursive Types and its Basic Usage

Types and Programming Languages. Lecture 5. Extensions of simple types

Design Principles of Programming Languages. Recursive Types. Zhenjiang Hu, Haiyan Zhao, Yingfei Xiong Peking University, Spring Term

Design Principles of Programming Languages. Recursive Types. Zhenjiang Hu, Haiyan Zhao, Yingfei Xiong Peking University, Spring Term, 2014

CS 4110 Programming Languages & Logics. Lecture 28 Recursive Types

CIS 500 Software Foundations Midterm I Answer key October 8, 2003

Derivation for the Necessity of Recursive Types and its Basic Usage

Goal. CS152: Programming Languages. Lecture 15 Parametric Polymorphism. What the Library Likes. What The Client Likes. Start simpler.

Types and Programming Languages. Lecture 6. Normalization, references, and exceptions

Subsumption. Principle of safe substitution

The University of Nottingham

Fall 2013 Midterm Exam 10/22/13. This is a closed-book, closed-notes exam. Problem Points Score. Various definitions are provided in the exam.

CS 4110 Programming Languages & Logics. Lecture 17 Programming in the λ-calculus

λ calculus Function application Untyped λ-calculus - Basic Idea Terms, Variables, Syntax β reduction Advanced Formal Methods

axiomatic semantics involving logical rules for deriving relations between preconditions and postconditions.

Programming Languages Lecture 14: Sum, Product, Recursive Types

CS611 Lecture 33 Equirecursive types & Recursive domain equations November 19, 2001

Symmetry in Type Theory

CIS 500 Software Foundations Midterm I

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

The University of Nottingham SCHOOL OF COMPUTER SCIENCE A LEVEL 4 MODULE, SPRING SEMESTER MATHEMATICAL FOUNDATIONS OF PROGRAMMING ANSWERS

Programming Languages Fall 2014

Negations in Refinement Type Systems

1 Introduction. 3 Syntax

Natural Numbers. We will use natural numbers to illustrate several ideas that will apply to Haskell data types in general.

Lecture Note: Types. 1 Introduction 2. 2 Simple Types 3. 3 Type Soundness 6. 4 Recursive Types Subtyping 17

Lecture Notes on Data Representation

Formal Systems and their Applications

CMSC 336: Type Systems for Programming Languages Lecture 5: Simply Typed Lambda Calculus Acar & Ahmed January 24, 2008

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

CS 6110 S11 Lecture 25 Typed λ-calculus 6 April 2011

CS-XXX: Graduate Programming Languages. Lecture 17 Recursive Types. Dan Grossman 2012

This is already grossly inconvenient in present formalisms. Why do we want to make this convenient? GENERAL GOALS

Concepts of programming languages

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Lecture Notes on Program Equivalence

Recursive Types. Chapter 7

CSE-505: Programming Languages. Lecture 20.5 Recursive Types. Zach Tatlock 2016

Inductive Definitions, continued

Overview. A normal-order language. Strictness. Recursion. Infinite data structures. Direct denotational semantics. Transition semantics

CSE-321 Programming Languages 2011 Final

Exercise 1 (2+2+2 points)

9.5 Equivalence Relations

λ calculus is inconsistent

Part III. Chapter 15: Subtyping

CIS 500 Software Foundations Fall October 2

Homework 3 COSE212, Fall 2018

Lambda Calculus. Type Systems, Lectures 3. Jevgeni Kabanov Tartu,

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Programming Languages Lecture 15: Recursive Types & Subtyping

Constrained Types and their Expressiveness

Propositional Logic. Part I

Denotational Semantics. Domain Theory

The Lambda Calculus. 27 September. Fall Software Foundations CIS 500. The lambda-calculus. Announcements

Recursive Types and Subtyping

CS 4110 Programming Languages & Logics. Lecture 27 Recursive Types

Lecture 9: Typed Lambda Calculus

CIS 500 Software Foundations Fall September 25

Lambda Calculi With Polymorphism

More Lambda Calculus and Intro to Type Systems

Exercise 1 ( = 22 points)

Resources: The slides of this lecture were derived from [Järvi], with permission of the original author, by copy & x = 1 let x = 1 in...

Lecture 9: More Lambda Calculus / Types

- M ::= v (M M) λv. M - Impure versions add constants, but not necessary! - Turing-complete. - true = λ u. λ v. u. - false = λ u. λ v.

Type Systems. Parametric Polymorphism. 1. Recall Let-Polymorphism. 1. Recall Let-Polymorphism. Lecture 9 Dec. 15th, 2004 Sebastian Maneth

CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Sections p.

CSC Discrete Math I, Spring Sets

Formal Semantics. Aspects to formalize. Lambda calculus. Approach

COMPUTABILITY THEORY AND RECURSIVELY ENUMERABLE SETS

COMP 4161 NICTA Advanced Course. Advanced Topics in Software Verification. Toby Murray, June Andronick, Gerwin Klein

Semantics via Syntax. f (4) = if define f (x) =2 x + 55.

The Untyped Lambda Calculus

Foundations of AI. 9. Predicate Logic. Syntax and Semantics, Normal Forms, Herbrand Expansion, Resolution

Inductive datatypes in HOL. lessons learned in Formal-Logic Engineering

Part III Chapter 15: Subtyping

Programming Language Concepts: Lecture 19

3 Pairs and Lists. 3.1 Formal vs. Informal Proofs

1 Problem Description

Lambda Calculus as a Programming Language

Costly software bugs that could have been averted with type checking

More Lambda Calculus and Intro to Type Systems

Exercise 1 ( = 18 points)

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

3.4 Deduction and Evaluation: Tools Conditional-Equational Logic

Chapter 5: The Untyped Lambda Calculus

INCREMENTAL SOFTWARE CONSTRUCTION WITH REFINEMENT DIAGRAMS

Programming Languages

CSE-321 Programming Languages 2010 Final

Foundations of Computer Science Spring Mathematical Preliminaries

Programming Languages Fall 2013

Program verification. Generalities about software Verification Model Checking. September 20, 2016

(Refer Slide Time: 4:00)

Semantics and Concurrence Module on Semantic of Programming Languages

The Untyped Lambda Calculus

Universes. Universes for Data. Peter Morris. University of Nottingham. November 12, 2009

CSE-321 Programming Languages 2012 Midterm

Transcription:

Types and Programming Languages Lecture 8. Recursive type Xiaojuan Cai cxj@sjtu.edu.cn BASICS Lab, Shanghai Jiao Tong University Fall, 2016

List[T] List[T] is a type constructor whose elements are lists with elements of type T. A list is either null or else a pair (cons cell) of an element and another list. Similar structures include: queues, binary trees, etc. We need a general mechanism with which they can be defined from simpler elements. This mechanism is called recursive types. The system studied in this lecture is simply typed λ-calculus with recursive types. And we will only focus on NatList. Another mechanism for List[T] is type operator (Chapter 29).

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

Recursive types How to define the type NatList? It s a variant type: NatList =< nil : Unit, cons : {Nat,...} > The... is another list of number! NatList =< nil : Unit, cons : {Nat, NatList} > Above definition will introduce divergence. Like recursive functions, we introduce an explicit recursion operator µ for types: NatList = µx. < nil : Unit, cons : {Nat, X} >

NatList operations Recall in Figure 11-13, we define lots of operations for List[T] as built-in. Here we will define them as functions. nil = <nil = unit> as NatList; cons = λn:nat.λl:natlist.<cons = {n,l}> as NatList; isnil = λl : NatList. case l of < nil = u > true < cons = p > false hd = λl : NatList. case l of < nil = u > 0 < cons = p > p.1 tl = λl : NatList. case l of < nil = u > 0 < cons = p > p.2

NatList functions sumlist = fix (λs : NatList Nat. λl : NatList. case l of < nil = u > 0 < cons = p > plus p.1 (s p.2)) mylist = cons 2 (cons 3 (cons 5 nil)) sumlist mylist returns 10.

Hungry functions Hungry = µa.nat-> A f = fix (λf:hungry.λn:nat.f) f 0 1 2 3 4 5;

Streams Stream is the type of functions that can produce an arbitrary number of numbers (or other types). Stream = µa. Unit->{Nat,A} hd = λs:stream.(s unit).1; tl = λs:stream.(s unit).2; But how to define a stream? upfrom0 = fix (λf:nat->stream.λn:nat.λ :Unit.{n,f (succ n)}) 0; hd upfrom0 returns 0. hd (tl (tl (tl upfrom0))) returns 3. Quiz. Define a stream that yields all the elements to be 1. ones = fix (λs:stream.λ :Unit.{1,s})

Processes Processes are functions that accept a number and return a number and a new process. Process = µa. Nat->{Nat,A} p = fix (λf:nat->process.λacc.λn:nat. let newacc = plus acc n in {newacc,f newacc}) 0; curr = λs:process.(s 0).1 send = λn:nat.λs:process.(s n).2 curr (send 20 (send 3 (send 5 p))) returns 28.

Objects Processes are similar to objects which interacting with data. Counter = µc.{get:nat, inc:unit->c} c = let create = fix in create {x=0} (λf:{x:nat}->counter.λs:{x:nat}. {get = s.x, inc = λ :Unit.f {x=succ(s.x)}) c1 = c.inc unit; c2 = c1.inc unit; c2.get;

Recursive values from recursive types A more surprising use of recursive types is a well-typed implementation of the fixed-point combinator. Quiz. Please rewrite the fix-point operator into simply typed λ-term with recursive type. fix = λf.(λx.f(x x))(λx.f(x x)) fix T = λf : T T.(λx : (µa.a T).f (x x)) (λx : (µa.a T).f (x x); Recursive types break the strong normalization property: diverge T = λ : Unit.fix T (λx : T.x) This reveals the expressive power of recursive types.

Untyped λ-calculus Moreover, we can embed the whole untyped λ-calculus into a statically typed language with recursive types. D = µx.x->x lam = λf:d->d.f as D ap = λf:d.λa:d.f a Here comes the encoding from untyped λ-calculus into a well-typed one: x = x λx.m = lam (λx : D. M ) M N = ap M N

Untyped λ-calculus with other features If we extend untyped λ-calculus with numbers, then the whole datatype is extended to be a variant type. D = µx.<nat:nat, fn:x->x> ap = λf:d.λa:d.case f of <nat=n> diverge D <fn = f> f a unit

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

Formalities There are two basic approaches to recursive types. The essential difference is their reponse to the question: What is the relation between the type µx.t and its one-step unfolding? For example, NatList and <nil:unit, cons:{nat,natlist}>. The equi-recursive approach takes these two expressions definitionally equal interchangeable in any context. The iso-recursive approach takes these two expression different, but isomorphic.

Equi-recursive Pros: More intuitive; Match with all the previous presentations. Definitions, safety theorems and even proofs remains unchanged. Cons: The implementation requires some work, Since type checking can not work directly with infinite structures. (Chapter 21) Interactions with other advanced features, such as quantification, lead to theoretical difficulties, even undecidability.

Iso-recursive The unfolding of µx.t is using the standard notation for substitution: unfolds to NatList = µx. < nil : Unit, cons : {Nat, X} > < nil : Unit, cons : {Nat, µx. < nil : Unit, cons : {Nat, X} >} > We need to introduce fold[µx.t] and unfold[µx.t] explicitly into syntax.

Iso-recursive: pros and cons Pros: Less work for type systems. Easy to interact with other features. Cons: Heavier: requiring programs to be decorated with fold and unfold. Iso-recursive is quite palatable in practice. Since the fold and unfold notations can be hidden by coalescing them with other annotations. Each use of constructors is to build a value with implicitly include a fold; Each use of case implicitly forces an unfold.

Subtyping Assume Even is a subtype of Nat. What the relation between these two types? µx.nat (Even X) and µx.even (Nat X)

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

Coming soon We will develop the theoretical foundations of typecheckers for equi-recursive types. We will deal with a system including both recursive types and subtyping. We will use coinduction to make equi-recursive types precise.

Induction and coinduction Let s fix some universal set U, which denotes everything in the world. Definition. A function F P(U) P(U) is monotone if X Y implies F (X ) F (Y ), where P(U) is the powerset of U. In the following, F is always monotone, also called as generating function. Definition. Let X be a subset of U. X is F -closed if F (X ) X. X is F -consistent if X F (X ). X is a fixed point if X = F (X ).

Example Consider the three-element universe U = {a, b, c}: E 1 ( ) = {c} E 1 ({a, b}) = {c} E 1 ({a}) = {c} E 1 ({a, c}) = {b, c} E 1 ({b}) = {c} E 1 ({b, c}) = {a, b, c} E 1 ({c}) = {b, c} E 1 ({a, b, c}) = {a, b, c} {a, b, c} is E 1 -closed;, {c}, {b, c} and {a, b, c} are E 1 -consistent; {a, b, c} is a fixed point of E 1. Actually, E 1 can be represented as a set of inference rules: c c b b c a

Knaster-Tarski theorem Theorem [Knaster-Tarski]. The intersection of all F -closed sets is the least fixed point of F, denoted µf ; The union of all F -consistent sets is the greatest fixed point of F, denoted νf. Example. (continued) µe 1 = νe 1 = {a, b, c}. Corollary. Principle of induction: If X is F -closed, then µf X ; Principle of coinduction: If X is F -consistent, then X νf ;

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

Finite and infinite types Definition. A tree type is a partial function T {1, 2} {,, Top} satisfying: T ( ) is defined; if T (π, σ) is defined then T (π) is defined; if T (π) = or T (π) =, then T (π, 1) and T (π, 2) are defined; if T (π) = Top, then T (π, 1) and T (π, 2) are undefined;

An alternative definition for finite tree types A tree type T is finite if dom(t ) is finite. The set of finite tree types can be defined more compactly by a grammar: T ::= Top T T T T The set of all finite tree types is the least fixed point of the generating function described by the grammar. The set of all tree types is the greatest fixed point of the generating function described by the grammar.

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

Subtyping for finite types Definition 21.3.1. Two finite tree types S and T are in the subtype relation if (S, T ) µs f, where the monotone function S f P(T f T f ) P(T f T f ) is defined by S f (R) = {(T, Top) T T f } {(S 1 S 2, T 1 T 2 ) (S 1, T 1 ), (S 2, T 2 ) R} {(S 1 S 2, T 1 T 2 ) (T 1, S 1 ), (S 2, T 2 ) R}. Quiz. Give a set of inference rules that precisely capture the function above.

Subtyping for infinite types Definition 21.3.2. Two tree types S and T are in the subtype relation if (S, T ) νs, where the monotone function S P(T T ) P(T T ) is defined by Quiz. S(R) = {(T, Top) T T } {(S 1 S 2, T 1 T 2 ) (S 1, T 1 ), (S 2, T 2 ) R} {(S 1 S 2, T 1 T 2 ) (T 1, S 1 ), (S 2, T 2 ) R}. Check that νs is not the whole of T T.

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

Membership checking How to decide, given a generating function F on some universe U and an element x U, whether or not x νf? An element x may generated from some set X such that x F (X ). We call X the generating set for x. There are minimal generating set for x. We will furthur focus on the class of invertible functions, where each x has at most one minimal generating set.

Invertible generating functions Definition. A generating function F is said to be invertible if, for all x U, the collection of sets G x = {X U x F (X )} either is empty or contains a unique member that is a subset of all the others. Definition. If F is invertible, the partial function support F U P(U) is defined as follows: { X if X Gx and X support F (x) = G x.x X if G x = Which can be lifted to sets: { support F (X ) = x X support F (x) if x X.support F (x) o.w.

Towards an algorithm An element x is F -supported if support F (x) ; Otherwise, x is F -unsupported. An F -supported element is called F -ground if support F (x) =. An invertible function can be visualized as a support graph. Quiz. Give the inference rules for this function E.

gfp F funciton Definition. Suppose F is an invertible generating function. Define the boolean valued function gfp F (or just gfp) as follows: gfp(x ) = if support(x ), then false else if support(x ) X, then true else gfp(support(x ) X ). If gfp(x) = gfp({x}) returns true, then x νf ; If it returns false, x νf. The remainder of this part is devoted to proving the correctness and termination of gfp.

Correctness Lemma 21.5.7. X F (Y ) iff support F (X ) and support F (X ) Y. Lemma 21.5.8. Suppose P is a fixed point of F. Then X P iff support F (X ) and support F (X ) P. Theorem 21.5.9. If gfp(x ) = true, then X νf ; If gfp(x ) = false, then X νf ;

Termination Given an invertible generating function F, and an element x U: { if support(x) pred(x) = support(x) if support(x) pred(x ) = x X pred(x). reachable(x ) = n 0 pred n (X ). F is finite state if reachable(x) is finite for any x U. Theorem 21.5.12. if reachable(x ) is finite, then gfp(x ) terminates for any finite X U.

Coming soon We have algorithms for checking membership of νf for some invertible and finite state generating function F. Now we will consider our subtyping function S, which is invertible but may not be finite state. We will show that the algorithms always terminate for regular type trees.

Subtrees Definition. A tree type S is a subtree of a tree type T if S = λσ.t (π, σ) for some π. Definition. A tree type T T is regular if subtrees(t ) is finite, i.e., if T has finitely many distinct subtrees. The set of regular tree types is written T r.

Examples Every finite tree type is regular, for example, T = Top->(Top Top); Some infinite tree types are regular, for example, T = Top (Top (Top...)); Some infinite tree types are irregular, for example, T=B (A (B (A (A (B (A (A (A (B...))))))))) Proposition. The restriction S r of generating function S on T r is finite state.

Outline Recursive types Formalities Metatheory of recursive types Induction and coinduction Finite and infinite types Subtyping Membership checking Regular trees µ-types

µ-types The set of raw µ-types can be defined by this grammar: T ::= X Top T T T T µx.t Not all the raw µ-types can be reasonably interpreted as representations of tree types, for example µx.x. Definition. A raw µ-type T is contractive if, for any subexpression of T of the form µx.µx 1.µX 2...µX n.s the body S is not X. µ-types are contractive raw µ-types. The set of µ-types are denoted as T m. We write µ-height(t ) for number of µ-bindings at the front of T.

From µ-types to tree types Definition. The function treeof, mapping closed µ-types to tree types, is defined inductively as follows: treeof(top)( ) = Top treeof(t 1 T 2 )( ) = treeof(t 1 T 2 )(i, π) = treeof(t i )(π) treeof(t 1 T2)( ) = treeof(t 1 T 2 )(i, π) = treeof(t i )(π) treeof(µx.t)(π) = treeof([x µx.t]t)(π) Example. What is treeof (µx.((x Top) X)). Every recursive use of treeof on the right-hand side reduces the lexicographic size of the pair ( π, µ-height(t )); All recursive calls preserve contractiveness and closure of the argument types.

Subtyping for µ-types S <: [X µx.t]t S <: µx.t [X µx.s]s <: T µx.s <: T We modify the subtyping generation function from S to S m. Definition 21.8.4. Two finite tree types S and T are in the subtype relation if (S, T ) νs m, where the monotone function S m P(T m T ) P(T m T m ) is defined by S m (R) = {(T, Top) T T } {(S 1 S 2, T 1 T 2 ) (S 1, T 1 ), (S 2, T 2 ) R} {(S 1 S 2, T 1 T 2 ) (T 1, S 1 ), (S 2, T 2 ) R} {(S, µx.t ) (S, [X µx.t ]T ) R} {(µx.s, T ) ([X µx.s]s, T ) R, T Top, and T µy.t 1 }.

Support function The generating function Sm is invertible because the corresponding support function is well-defined: support Sm (S, T ) = if T = Top {(S 1, T 1 ), (S 2, T 2 )} if S = S 1 S 2, T = T 1 T 2 {(T 1, S 1 ), (S 2, T 2 )} if S = S 1 S 2, T = T 1 T 2 {(S, [X µx.t 1 ]T 1 )} if T = µx.t 1 {([X µx.s]s, T )} if S = µx.s T Top, T µx.t 1

Correspondence Theorem. 21.8.7. Let (S, T ) T m T m. Then (S, T ) νs m iff treeof (S, T ) νs.

Subtyping iso-recursive types The most common definition of iso-recursive subtyping is the Amber rule, after Cardelli s Amber language (1986): S-Amber Σ, X <: Y S <: T Σ µx.s <: µy.t Quiz. Find recursive types S and T such that S <: T using the equi-recursive definition, but not using the Amber rule. Answer: µx.nat (Nat X) and µx.nat X

Conclusion Recursive types can be defined by using µ operator. Recursive types are quite expressive: with it we can embed the whole untyped λ-calculus into well-typed λ-calculus. Iso-recursive is heavy weight with notations, but easy to implement. Equi-recursive is very natural but really needs lots of work to build the type system. Coinduction is a standard method to handle infinite structures. Subtyping relation of equi-recursive types needs to compute the greatest fixed point of a subtyping generating function.

Homework 20.1.1 (without testing part), 20.1.2, 21.1.7, 21.3.4, 21.11.1.