Example: typing ; α : [ ⊤ ] ⊢ throw α nil : ⊤ ; α : [ ⊤ ] ⊢ nil : [ ⊤ ] ; α : [ ⊤ ] ⊢ ( throw α nil ) :: nil : [ ⊤ ] ; ⊢ catch α . ( throw α nil ) :: nil : [ ⊤ ] How to think of this derivation: 1. Our goal is [ ⊤ ] 2. We save the current continuation as α 3. We construct a singleton list . . . leaving us to construct a term of type ⊤
Example: typing ; α : [ ⊤ ] ⊢ nil : [ ⊤ ] ; α : [ ⊤ ] ⊢ throw α nil : ⊤ ; α : [ ⊤ ] ⊢ nil : [ ⊤ ] ; α : [ ⊤ ] ⊢ ( throw α nil ) :: nil : [ ⊤ ] ; ⊢ catch α . ( throw α nil ) :: nil : [ ⊤ ] How to think of this derivation: 1. Our goal is [ ⊤ ] 2. We save the current continuation as α 3. We construct a singleton list . . . leaving us to construct a term of type ⊤ 4. But instead we jump back to α with nil
Reduction Values: v , w ::= x | () | nil | (::) | (::) v | (::) v w | lrec | lrec v r | lrec v r v s | λ x . r
Reduction Values: v , w ::= x | () | nil | (::) | (::) v | (::) v w | lrec | lrec v r | lrec v r v s | λ x . r Reduction: ( λ x . t ) v → t [ x := v ] lrec v r v s nil → v r lrec v r v s ( v h :: v t ) → v s v h v t ( lrec v r v s v t )
Reduction Values: v , w ::= x | () | nil | (::) | (::) v | (::) v w | lrec | lrec v r | lrec v r v s | λ x . r Contexts: E ::= � t | v � | throw β � Reduction: ( λ x . t ) v → t [ x := v ] lrec v r v s nil → v r lrec v r v s ( v h :: v t ) → v s v h v t ( lrec v r v s v t ) E [ throw α t ] → throw α t
Reduction Values: v , w ::= x | () | nil | (::) | (::) v | (::) v w | lrec | lrec v r | lrec v r v s | λ x . r Contexts: E ::= � t | v � | throw β � Reduction: ( λ x . t ) v → t [ x := v ] lrec v r v s nil → v r lrec v r v s ( v h :: v t ) → v s v h v t ( lrec v r v s v t ) E [ throw α t ] → throw α t catch α . throw α t → catch α . t
Reduction Values: v , w ::= x | () | nil | (::) | (::) v | (::) v w | lrec | lrec v r | lrec v r v s | λ x . r Contexts: E ::= � t | v � | throw β � Reduction: ( λ x . t ) v → t [ x := v ] lrec v r v s nil → v r lrec v r v s ( v h :: v t ) → v s v h v t ( lrec v r v s v t ) E [ throw α t ] → throw α t catch α . throw α t → catch α . t catch α . throw β v → throw β v if α / ∈ { β } ∪ FCV( v )
Reduction Values: v , w ::= x | () | nil | (::) | (::) v | (::) v w | lrec | lrec v r | lrec v r v s | λ x . r Contexts: E ::= � t | v � | throw β � Reduction: ( λ x . t ) v → t [ x := v ] lrec v r v s nil → v r lrec v r v s ( v h :: v t ) → v s v h v t ( lrec v r v s v t ) E [ throw α t ] → throw α t catch α . throw α t → catch α . t catch α . throw β v → throw β v if α / ∈ { β } ∪ FCV( v ) catch α . v → v if α / ∈ FCV( v )
Example: reduction catch α . ( throw α nil ) :: nil
Example: reduction catch α . ( throw α nil ) :: nil
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ]
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ]
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ] → catch α . throw α nil
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ] → catch α . throw α nil
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ] → catch α . throw α nil → catch α . nil
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ] → catch α . throw α nil → catch α . nil
Example: reduction catch α . ( throw α nil ) :: nil ≡ catch α . ( � :: nil )[ throw α nil ] → catch α . throw α nil → catch α . nil → nil
Why restrict to → -free types? (1) ⇒ t is a value or ∃ t ′ . t → t ′ Progress : ; ⊢ t : τ =
Why restrict to → -free types? (1) ⇒ t is a value or ∃ t ′ . t → t ′ Progress : ; ⊢ t : τ = ◮ Without the → -free restriction, the term catch α . λ x . throw α ( λ y . y ) : ⊤ → ⊤ would not reduce
Why restrict to → -free types? (1) ⇒ t is a value or ∃ t ′ . t → t ′ Progress : ; ⊢ t : τ = ◮ Without the → -free restriction, the term catch α . λ x . throw α ( λ y . y ) : ⊤ → ⊤ would not reduce ◮ Hence progress would fail
Why restrict to → -free types? (1) ⇒ t is a value or ∃ t ′ . t → t ′ Progress : ; ⊢ t : τ = ◮ Without the → -free restriction, the term catch α . λ x . throw α ( λ y . y ) : ⊤ → ⊤ would not reduce ◮ Hence progress would fail ◮ Note: an analogue term in the λµ -calculus µα. [ α ] λ x .µ . [ α ] λ y . y does not reduce either
Why restrict to → -free types? (2) Consequences of progress ◮ In Herbelin’s IQC MP : ◮ If ; ⊢ t : ρ ∨ σ , then ∃ t ′ . ; ⊢ t ′ : ρ or ; ⊢ t ′ : σ ◮ If ; ⊢ t : ∃ x . P ( x ), then ∃ t ′ . ; ⊢ t ′ : P ( t ′ )
Why restrict to → -free types? (2) Consequences of progress ◮ In Herbelin’s IQC MP : ◮ If ; ⊢ t : ρ ∨ σ , then ∃ t ′ . ; ⊢ t ′ : ρ or ; ⊢ t ′ : σ ◮ If ; ⊢ t : ∃ x . P ( x ), then ∃ t ′ . ; ⊢ t ′ : P ( t ′ ) ◮ In λ :: catch : ◮ Unique representation of data ◮ One-to-one correspondence between closed terms of N and N
Natural numbers We define a type N := [ ⊤ ], with: 0 := nil S := (::) () nrec := λ x r y s . lrec x r ( λ . x s ) Notation: n := S n 0
Inefficient predecessor We could define pred : N → N as pred := nrec 0 ( λ xh . x )
Inefficient predecessor We could define pred : N → N as pred := nrec 0 ( λ xh . x ) Inefficient with call-by-value reduction pred n ։ ( λ xh . x ) n − 1 ( pred n − 1)
Inefficient predecessor We could define pred : N → N as pred := nrec 0 ( λ xh . x ) Inefficient with call-by-value reduction pred n ։ ( λ xh . x ) n − 1 ( pred n − 1) ։ ( λ h . n − 1) ( pred n − 2) � �� � not a value
Inefficient predecessor We could define pred : N → N as pred := nrec 0 ( λ xh . x ) Inefficient with call-by-value reduction pred n ։ ( λ xh . x ) n − 1 ( pred n − 1) ։ ( λ h . n − 1) ( pred n − 2) � �� � not a value ։ ( λ h . n − 1) (( λ h . n − 2) ( pred n − 2) ) � �� � not a value
Inefficient predecessor We could define pred : N → N as pred := nrec 0 ( λ xh . x ) Inefficient with call-by-value reduction pred n ։ ( λ xh . x ) n − 1 ( pred n − 1) ։ ( λ h . n − 1) ( pred n − 2) � �� � not a value ։ ( λ h . n − 1) (( λ h . n − 2) ( pred n − 2) ) � �� � not a value ։ . . .
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n )
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n )
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n )
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n )
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . ( throw α n ) ( lrec 0 ( λ x . throw α x ) n )
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . ( throw α n ) ( lrec 0 ( λ x . throw α x ) n ) We use the rule ( throw α t ) r → throw α t to discard the recursive call
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . ( throw α n ) ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . throw α n We use the rule ( throw α t ) r → throw α t to discard the recursive call
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . ( throw α n ) ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . throw α n
A more efficient predecessor in λ :: catch We redefine pred : N → N as pred := λ n . catch α . nrec 0 ( λ x . throw α x ) n Using catch and throw it becomes more efficient pred n + 1 ։ catch α . nrec 0 ( λ x . throw α x ) ( S n ) ։ catch α . ( λ x . throw α x ) n ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . ( throw α n ) ( lrec 0 ( λ x . throw α x ) n ) ։ catch α . throw α n ։ n
Example: list multiplication ◮ We want to define F : [ N ] → N such that F [ t 1 , . . . , t n ] = t 1 ∗ . . . ∗ t n
Example: list multiplication ◮ We want to define F : [ N ] → N such that F [ t 1 , . . . , t n ] = t 1 ∗ . . . ∗ t n ◮ The straightforward definition F := lrec 1 ( λ x h . x ∗ h ) continues to multiply once a zero has been encountered
Example: list multiplication ◮ We want to define F : [ N ] → N such that F [ t 1 , . . . , t n ] = t 1 ∗ . . . ∗ t n ◮ The straightforward definition F := lrec 1 ( λ x h . x ∗ h ) continues to multiply once a zero has been encountered ◮ We use control to jump out when we encounter a zero F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]:
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9]
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9]
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9])
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9])
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9])
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9])
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( throw α 0 )
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( throw α 0 )
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( throw α 0 ) ։ catch α . throw α 0
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( throw α 0 ) ։ catch α . throw α 0
Example: list multiplication (continued) The definition of list multiplication: F := λ l . catch α . lrec 1 H l H := λ x . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) x A computation of F [4 , 0 , 9]: ։ catch α . lrec 1 H [4 , 0 , 9] ։ catch α . nrec ( throw α 0 ) ( λ y h . S y ∗ h ) 4 ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( lrec 1 H [0 , 9]) ։ catch α . ( λ h . 4 ∗ h ) ( throw α 0 ) ։ catch α . throw α 0 ։ 0
Properties of λ :: catch ◮ Subject reduction. Γ; ∆ ⊢ t : ρ and t → t ′ , then Γ; ∆ ⊢ t ′ : ρ ◮ A standard substitution lemma is needed ◮ Induction on the structure of t → t ′
Properties of λ :: catch ◮ Subject reduction. Γ; ∆ ⊢ t : ρ and t → t ′ , then Γ; ∆ ⊢ t ′ : ρ ◮ A standard substitution lemma is needed ◮ Induction on the structure of t → t ′ ◮ Progress. ; ⊢ t : ρ , then t is a value or ∃ t ′ , t → t ′ ◮ A simple generalization is needed ◮ Induction on the typing judgment.
Properties of λ :: catch ◮ Subject reduction. Γ; ∆ ⊢ t : ρ and t → t ′ , then Γ; ∆ ⊢ t ′ : ρ ◮ A standard substitution lemma is needed ◮ Induction on the structure of t → t ′ ◮ Progress. ; ⊢ t : ρ , then t is a value or ∃ t ′ , t → t ′ ◮ A simple generalization is needed ◮ Induction on the typing judgment. ◮ Confluence. t ։ r and t ։ s , then ∃ q . r ։ q and s ։ q
Properties of λ :: catch ◮ Subject reduction. Γ; ∆ ⊢ t : ρ and t → t ′ , then Γ; ∆ ⊢ t ′ : ρ ◮ A standard substitution lemma is needed ◮ Induction on the structure of t → t ′ ◮ Progress. ; ⊢ t : ρ , then t is a value or ∃ t ′ , t → t ′ ◮ A simple generalization is needed ◮ Induction on the typing judgment. ◮ Confluence. t ։ r and t ։ s , then ∃ q . r ։ q and s ։ q ◮ Strong Normalization. Γ; ∆ ⊢ t : ρ , then no infinite t → t 1 . . .
Parallel reduction Usual approach [Tait/Martin-L¨ of] 1. Define a parallel reduction ⇒ 2. Prove that ⇒ is confluent 3. Prove that t 1 → t 2 implies t 1 ⇒ t 2 4. Prove that t 1 ⇒ t 2 implies t 1 ։ t 2
Parallel reduction Usual approach [Tait/Martin-L¨ of] 1. Define a parallel reduction ⇒ 2. Prove that ⇒ is confluent 3. Prove that t 1 → t 2 implies t 1 ⇒ t 2 4. Prove that t 1 ⇒ t 2 implies t 1 ։ t 2 For the ordinary λ -calculus t ⇒ t ′ t ⇒ t ′ r ⇒ r ′ λ x . t ⇒ λ x . t ′ tr ⇒ t ′ r ′ x ⇒ x t ⇒ t ′ r ⇒ r ′ ( λ x . t ) r ⇒ t ′ [ x := r ′ ]
Parallel reduction for λ :: catch ◮ Consider the naive rule for throw t ⇒ t ′ E [ throw α t ] ⇒ throw α t ′
� � Parallel reduction for λ :: catch ◮ Consider the naive rule for throw t ⇒ t ′ E [ throw α t ] ⇒ throw α t ′ ◮ Problem: not confluent throw α 1 ( throw α 2 ( throw α 3 ( throw α 4 ( throw α 5 x )))) throw α 1 ( throw α 3 ( throw α 5 x )) throw α 2 ( throw α 4 ( throw α 5 x ))
� � Parallel reduction for λ :: catch ◮ Consider the naive rule for throw t ⇒ t ′ E [ throw α t ] ⇒ throw α t ′ ◮ Problem: not confluent throw α 1 ( throw α 2 ( throw α 3 ( throw α 4 ( throw α 5 x )))) throw α 1 ( throw α 3 ( throw α 5 x )) throw α 2 ( throw α 4 ( throw α 5 x )) ◮ Solution: jump over a compound context t ⇒ t ′ � E [ throw α t ] ⇒ throw α t ′
Complete development Define t ⋄ such that if t 1 ⇒ t 2 , then t 2 ⇒ t ⋄ 1 [Takahashi, 1995]
� � Complete development Define t ⋄ such that if t 1 ⇒ t 2 , then t 2 ⇒ t ⋄ 1 [Takahashi, 1995] Confluence of ⇒ is a direct consequence t 1 t 2 t 3
Recommend
More recommend