SLIDE 1
A typed -calculus with call-by-name and call-by-value iteration - - PowerPoint PPT Presentation
A typed -calculus with call-by-name and call-by-value iteration - - PowerPoint PPT Presentation
A typed -calculus with call-by-name and call-by-value iteration Herman Geuvers Radboud University Nijmegen and Eindhoven University of Technology The Netherlands Types 2015, Tallinn May 21, 2015 Contents Church data and Scott data
SLIDE 2
SLIDE 3
Church numerals
The most well-known Church data type := λx f .x p := λx f .f p (x) 1 := λx f .f x Succ := λn.λx f .f (n x f ) 2 := λx f .f (f x)
◮ The Church data types have iteration as basis. The numerals
are iterators.
◮ Iteration scheme for Nat. (Let D be any type.)
d : D f : D → D It d f : Nat → D with It d f 0 ։ d It d f (Succ x) ։ f (It d f x)
◮ Advantage: quite a bit of well-founded recursion for free. ◮ Disadvantage: no pattern matching built in; predecessor is
hard to define; the reduction is actually a conversion
SLIDE 4
Scott numerals
:= λx f .x n + 1 := λx f .f n 1 := λx f .f 0 succ := λp.λx f .f p 2 := λx f .f 1
◮ The Scott numerals are case distinctors. ◮ Case scheme for nat. (Let D be any type.)
d : D f : nat → D Case d f : nat → D with Case d f 0 ։ d Case d f (succ x) ։ f x
◮ Case d f := λx : nat.x d f . ◮ Advantage: the predecessor can immediately be defined:
pred := λp.p 0 (λy.y).
◮ Disadvantage: No recursion (which one has to get from
somewhere else, e.g. a fixed point-combinator).
SLIDE 5
Church and Scott for general data types
Given a data type with
◮ constructors c1, . . . , ck, ◮ with arity ar(i) of constructor ci.
The Church encoding is ci := λx1 . . . xar(i).λc1 . . . ck.ci (x1 c) . . . (xar(i) c) The Scott encoding is ci := λx1 . . . xar(i).λc1 . . . ck.ci x1 . . . xar(i)
SLIDE 6
Why study Scott data types?
◮ No recursion built in ⇒ more control over the definable
- functions. Brunel, Terui 2010; Baillot, De Benedetti, Ronchi
della Rocca 2014.
◮ Direct access to predecessor. Destructor is constant-time. ◮ Combined Church-Scott data types give Primitive Recursion
- scheme. For Nat, these are known as Parigot numerals. (See
also Stump, Fu 2014)
d : D f : Nat → D → D Rec d f : Nat → D Rec d f 0 ։ d Rec d f (Succ x) ։ f x (Rec d f x)
One can define Rec in terms of It, but that’s painful. (This is what Kleene found out at the dentist.)
SLIDE 7
Typing Church and Scott data types
◮ Church data types can be typed in polymorphic λ-calculus, λ2.
E.g. for Church numbers: Nat := ∀X.X → (X → X) → X.
◮ To type Scott data types we need λ2µ: λ2 + positive
recursive types:
◮ µX.Φ is well-formed if X occurs positively in Φ. ◮ Equality on types is the congruence generated from
µX.Φ = Φ[µX.Φ/X].
◮ Additional derivation rule:
Γ ⊢ M : A A = B Γ ⊢ M : B
E.g. for Scott numerals: nat := µY .∀X.X → (Y → X) → X. We will use this as nat = ∀X.X → (nat → X) → X.
SLIDE 8
The system λ2µIt
The system λ2µIt combines polymorphic lambda calculus with positive recursive types and CBN and CBV iterators. T := TVar | (T → T) | µTVar.T | ∀TVar.T, x : A ∈ Γ Γ ⊢ x : A Γ ⊢ M : A → B Γ ⊢ N : A Γ ⊢ M N : B Γ, x : A ⊢ M : B Γ ⊢ λx : A.M : A → B Γ ⊢ x : A if A = B Γ ⊢ x : B Γ ⊢ M : ∀X.A Γ ⊢ M : A[B/X] Γ ⊢ M : A if X / ∈ FV(Γ) Γ ⊢ M : ∀X.A The evaluation relation is weak-head reduction, →wh given by (λx.M)P →wh M[P/x] M →wh N M P →wh N P Plus additional typing and reduction rules for Itcbv and Itcbn.
SLIDE 9
Call-by-name and call-by-value iteration
To be able to define functions on Scott data types, we add for every data-type two program rules for iteration:
◮ Itcbn for call-by-name iteration from data-type D to B,
Idea: compute first constructor of the output of type B and pass to the appropriate continuation for type B.
◮ Itcbv for call-by-value iteration from data-type D to B.
Idea: compute input value completely and then pass on to a continuation of type B→X. So, this function will be of type ∀X.(B → X) → (D → X) To be abbreviated to ∀X.¬XB → ¬XD
SLIDE 10
Data types in λ2µIt
Data types have the following shape D = µT.∀X.(Φ1(T) → X) . . . → (Φn(T) → X) → X, with X positive in Φi(X). Phrased differently: D = ∀X.(Φ1(D) → X) . . . → (Φn(D) → X) → X, Examples: bool := ∀X.X → X → X nat := ∀X.X → (nat → X) → X listA := ∀X.X → (A → listA → X) → X btreeA := ∀X.(A → X) → (btreeA → btreeA → X) → X
SLIDE 11
Constructors are defined terms in λ2µIt
nat := ∀X.X → (nat → X) → X listA := ∀X.X → (A → listA → X) → X The constructors are (without type information with the λ): zero := λz.λs.z : nat succ := λn.λz.λs.s n : nat → nat nil := λn.λc.n : listA cons := λa.λl.λn.λc.c a l : A → listA → listA We write d for the encoding of a data-element as a term. So, for n ∈ N, n : nat, given by := zero n + 1 := succ n
SLIDE 12
Derivation rule for Itcbn, Call-by-Name iterator
Given D = ∀X.(Φ1(X) → D) . . . → (Φn(X) → D) → X. f1 : Φ1(B) → B . . . fn : Φn(B) → B ItcbnD
B f1 . . . fn : D → B
Plus reduction rule If B is also a data-type, we have B = ∀X.(Ψ1(X) → B) . . . → (Ψm(X) → B) → X. We could also write the rule for Itcbn as follows (for A an arbitrary type): f1 : Φ1(B) → B . . . fn : Φn(B) → B d : D c1 : Ψ1(B) → A . . . cm : Ψm(B) → A ItcbnD
B f1 . . . fn d c1 . . . cm : A
Idea: c1 : Ψ1(m) → A . . . cm : Ψm(B) → A are the continuations for data type B, one for each constructor of B.
SLIDE 13
Derivation rule for Itcbv, Call-by-Value iterator
Idea: ¬AB := B → A is the type of the continuation; c : ¬AB is called “after the value has been computed”. Let D = ∀X.(Φ1(X) → D) . . . → (Φn(X) → D) → X. f1 : ¬AB → ¬AΦ1(B) . . . fn : ¬AB → ¬AΦn(B) ItcbvD
B f1 . . . fn : ¬AB → ¬AD
Plus reduction rule This rule can also be phrased in “fully applied form”: f1 : ¬AB → ¬AΦ1(B) . . . fn : ¬AB → ¬AΦn(B) c : ¬AB d : D ItcbvD
B f1 . . . fn c d : A
SLIDE 14
Call-by-name and call-by-value iteration for nat
We show the case for nat = ∀X.X → (nat → X) → X. Call-by-name: f1 : B f2 : B → B Itcbn f1 f2 : nat → B with reduction rule: Itcbn f1 f2 n → n f1 (λx : nat.f2 (Itcbn f1 f2 x)) Call-by-value: f1 : ¬A¬AB f2 : ¬AB → ¬AB Itcbv f1 f2 : ¬AB → ¬Anat with reduction rule: Itcbv f1 f2 c n → n (f1 c) (Itcbv f1 f2 (f2 c)). Note: f1 c : A and Itcbv f1 f2 (f2 c) : nat → A.
SLIDE 15
Example for the case nat: Call-by-Value Addition
f1 : ¬A¬Anat f2 : ¬Anat → ¬Anat Itcbv f1 f2 : ¬Anat → ¬Anat Define:
- succ := λc : ¬Anat.λn : nat.c (succ n) : ¬Anat → ¬Anat
ˆ n := λc : ¬Anat.c n : ¬A¬Anat (for n : nat) Then AddCBV : nat → nat → ¬A¬Anat AddCBV := λx y : nat.λc : ¬Anat.Itcbv ˆ y succ c x We have AddCBV n m c ։ c n + m where n represents the number n.
SLIDE 16
Example for the case nat: Call-by-Name Addition
f1 : nat f2 : nat → nat Itcbn f1 f2 : nat → nat AddCBN := λx y : nat.Itcbn y succ. Then AddCBN n + 1 m ։ succ(AddCBN n m) ։ λz s.s(AddCBN n m)
◮ Weak-head reduction stops here. ◮ AddCBN t q computes the first ‘pattern’ of the output and
passes it on to the appropriate continuation. (In this case s.)
SLIDE 17
Storage operators
The idea of a storage operator (Krivine, Nour), Stor, for the natural numbers nat is: For every n ∈ N there is a term tn such that, given f : nat → A and M : nat with M =βvn n, Stor M f ։ f tn. To compute f M call-by-value, we compute Stor M f . This will first compute M and then feed this into f .
SLIDE 18
Storage operators in λ2µIt
A storage operator for data type D is a term Stor : D → ∀X.¬X¬XD satisfying, for all M with M =βvn d, Stor M f ։ f d. Define Stornat : nat → ∀X.¬X¬Xnat and Unstornat : (∀X.¬X¬Xnat) → nat as follows. Stornat := λn.λf .Itcbv zero succ f n Unstornat := λf .λz s.f (λn.n z s) with zero := λc.c zero, succ := λc m.c(succ m). Lemma The term Stornat is a storage operator for nat and Unstornat(Stornat n) =βvn n for all n ∈ N.
SLIDE 19
Strong Normalization
The proof uses the well-known saturated sets construction to give an interpretation for types as sets of (untyped) terms. X is a saturated set (X ∈ SAT) if
- 1. X ⊆ SN,
- 2. for x a variable and
P a sequence of terms, x P ∈ X, if x P ∈ SN,
- 3. X is closed under reduction: if M ∈ X and M ։ N, then
N ∈ X,
- 4. X is closed under weak-head-redex expansion: if M ∈ X and
N →wh M, then N ∈ X,
SLIDE 20
Question: how to intepret a data type as a saturated set?
◮ nat consists of specific closed λ-terms: zero, succ, . . . ◮ Itcbv and Itcbn impose closure conditions on [
[nat] ], and possibly on the interpretation of other types. SAT is a complete lattice, so we will define [ [nat] ] := NAT, where NAT is the least fixed point of some monotone N : SAT → SAT.
SLIDE 21
Intepreting nat
[ [nat] ] := NAT, where NAT := lfp(N), with N : SAT → SAT defined by N(X) := {M ∈ Term | M ∈
- T∈SAT
T → (X → T) → T ∧ M satisfies (I) and (II)}, where (I) and (II) are defined by (I) ∀B, A ∈ SAT ∀f1 ∈ ¬A¬AB ∀f2 ∈ ¬AB → ¬AB ∀c ∈ ¬AB, Itcbv f1 f2 c M ∈ A (II) ∀B ∈ SAT ∀f1 ∈ B ∀f2 ∈ B → B, Itcbn f1 f2 M ∈ B
SLIDE 22
Properties of [ [nat] ] := NAT
◮ N is monotone and X ∈ SAT ⇒ N(X) ∈ SAT. ◮ NAT satisfies the desired fixed point equation:
NAT =
- T∈SAT
T → (NAT → T) → T.
◮ As a consequence ⊢ t : nat ⇒ t ∈ NAT. ◮ The SN proof now follows from the soundness of the
SAT-model.
◮ The proof can be generalised to other data types.
SLIDE 23
Are Itcbv and Itcbn needed as primitives?
Equationally, Call-by-value can be defined by Call-by-name. For the nat case assume CBN: f1 : B f2 : B → B Itcbn f1 f2 : nat → B with reduction rule: Itcbn f1 f2 n → n f1 (λx : nat.f2 (Itcbn f1 f2 x)) Then f1 : ¬A¬AB f2 : ¬AB → ¬AB ˆ f2 : ¬A¬AB → ¬A¬AB Itcbn f1 ˆ f2 : nat → ¬A¬AB λc.λn.Itcbn f1 ˆ f2 n c : ¬AB → ¬Anat Define this term as Itcbv f1 f2. This function computes CBV and: Itcbv f1 f2 c zero ։ f1 c Itcbv f1 f2 c (succ y) =βvn Itcbv f1 f2 (f2 c) y.
SLIDE 24
Can we mediate between Scott nat and Church Nat?
◮ From Church to Scott: F : Nat → nat
F := λn.n zero succ
◮ From Scott to Church: G : nat → Nat
G := Itcbn Zero Succ
◮ From Scott to Church, call-by-value: H : ¬ANat → ¬Anat
H := Itcbv Zero Succ with Zero : ¬A¬ANat, Succ : ¬ANat → ¬ANat. With F, we can transform any function on Scott numerals into a (call-by-name) function on Church numerals: If f : nat → A then f ◦ F : Nat → A For encoded numerals we have f (Fn) =βvn f n So all function representable on nat are representable on Nat.
SLIDE 25
Can we mediate between Scott nat and Church Nat?
◮ From Scott to Church: G : nat → Nat
G := Itcbn Zero Succ
◮ From Scott to Church, call-by-value: H : ¬ANat → ¬Anat
H := Itcbv Zero Succ with Zero : ¬A¬ANat, Succ : ¬ANat → ¬ANat. With H, we can transform any function on Church numerals into a (call-by-value) function on Scott numerals: If f : Nat → A then H f : nat → A With G, we can transform any function on Church numerals into a (call-by-name) function on Scott numerals: If f : Nat → A then f ◦ G : nat → A For encoded numerals we have f (Gn) =βvn f n So all functions representable on Nat are representable on nat.
SLIDE 26
Can we define a constant-time predecessor for Church Nat?
Remember that pred : nat → nat is defined by pred n := n zero (λx.x). So we can define Pred : Nat → Nat by composing Nat
F
− → nat
pred
− → nat
G
− → Nat
◮ NOT in general Pred(Succ t) =βvn t. ◮ Predn + 1 ։ n (for encodings of numbers). ◮ Predn + 1 ։ n in O(n) steps.
Open question: can we improve on this? (Or can we prove it cannot be improved?)
SLIDE 27