Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Declarative Programming and (Co)Induction
Davide Ancona, Giovanni Lagorio and Elena Zucca
University of Genova
PhD Course, DISI, June 13-17, 2011
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 1 / 106
Plan of the course
1 Induction: inductive definitions and proofs by induction2 Small step and big step semantics, lambda calculus, inductive type
system, soundness3 Functional programming in Haskell4 Lab: exercises in Haskell5 Lab: implementation of the inductive type system in Haskell6 Induction and coinduction: lowest and greatest fixed points, proofs by
induction and by coinduction7 Abstract and operational semantics of Prolog and coProlog8 Programming in Prolog and coProlog9 Lab: exercises in Prolog and coProlog10 Lab: implementation of the inductive and coinductive type system in
Prolog/coProlog
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 2 / 106
Part 1Induction
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 3 / 106
Induction
What is induction useful for?definition of sets whose elements can be generated in a finite number ofsteps:
I natural numbers, finite lists, finite treesI relations and functions over such sets
proving properties by the induction principle
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 4 / 106
Simple examples
Mathematical styleThe set of even numbers is the least set s.t. (or: the set inductivelydefined by)
I 0 is an even numberI if n is an even number, then n + 2 is an even number
Recursive function definitions in programming languagesf x = if x == 0 then 0 else f (x-1) + 1
Syntax of programming languages
t ::= true | false | if t then t1 else t2 | succ t| pred t | 0 | iszero t
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 5 / 106
Inference systems
U universe
a rule is a pairPrc
, with Pr ⊆ U set of premises, c ∈ U consequence
an inference system Φ is a set of rules
Φ is finitary if, for allPrc∈ Φ, Pr is finite
X ⊆ U is closed w.r.t.Prc
iff Pr ⊆ X implies c ∈ X
X is Φ-closed (closed w.r.t. Φ) iff it is closed w.r.t all rules in Φ
the set I(Φ) inductively defined by Φ is the intersection of all the Φ-closedsetsit is easy to see that I(Φ) is Φ-closed, hence we can equivalently say theleast Φ-closed setU is always Φ-closed hence I(Φ) is well-definedgiven Φ, we can take as universe the set of consequence elements,hence it is not necessary to fix U
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 6 / 106
Inductive definitions
an inductive definition is any finite description, in some meta-language, ofan inference system Φ, hence of I(Φ)
typically consisting of a set of meta-rules of the formprece
cond
pre, ce, cond are expressions with meta-variableseach meta-rule represents a (possibly infinite) set of rules, one for eachassignment of values to the meta-variables satisfiyng condmeta-rules with empty set of premises are the basis, others are theinductive step of the inductive definitionhowever, there are many other styles for giving inductive definitions ...
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 7 / 106
Example: mathematical style
The set of even numbers is the least set s.t. (or: the set inductivelydefined by)
0 is an even numberif n is an even number, then n + 2 is an even number
corresponds to the following (meta-)rules, where n ranges over N:
0n
n + 2closed sets: {n | n even or n ≥ k} for some k ∈ Nnon closed sets: e.g., ∅
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 8 / 106
Variants
nn + 2
empty set
10n + 1
n0..10
0n
n + 2{n | n even}
1N
it is easy to see that I(Φ) 6= ∅ only if there is some rule with empty set ofpremises
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 9 / 106
Recursive function definitions in programminglanguages
f x = if x == 0 then 0 else f (x-1) + 1
corresponds to the following (meta-)rules, where x , r range over Z:
(0,0)
(x − 1, r)
(x , r + 1)x 6= 0
(some) closed sets: all the partial identity functions defined from somex ≤ 0, the total identity function, ...exercise: show that I(Φ) = {(x , x) | x ≥ 0}
I I(Φ) ⊆ {(x , x) | x ≥ 0} is proved showing that {(x , x) | x ≥ 0} is closedI {(x , x) | x ≥ 0} ⊆ I(Φ) by arithmetic induction
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 10 / 106
Example: syntax of programming languages
t ::= true | false | if t then t1 else t2| 0 | succ t | pred t | iszero t
corresponds to the following (meta-)rules:
true false
t t1 t2if t then t1 else t2
0t
succ tt
pred tt
iszero t
context free grammars correspond to a special class of inductivedefinitions where premises are distinct metavariables
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 11 / 106
An alternative view
Definition (Signature)A signature Σ is a family of operators indexed over natural numbers. Ifop ∈ Σn, then we say that op has arity n and write op/n
Definition (Terms over a signature)Given a signature Σ, the set of terms over Σ or Σ-terms is inductively definedby:for each operator op with arity n, if t1, . . . , tn are terms, then op(t1, . . . , tn) is aterm
for simplicity we consider the uni-sorted casea context-free grammar implicitly defines a signature and, for eachoperator, a concrete syntax for writing op(t1, . . . , tn), e.g.,if t then t1 else t2the signature is the abstract syntax
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 12 / 106
Induction principle
Φ inference system, I(Φ) ⊆ U , P : U → {T ,F}
Theorem
If for allPrc∈ Φ
(?) (P(d) = T for all d ∈ Pr) implies P(c) = T
then P(d) = T for all d ∈ I(Φ)
Proof.Set C = {d |P(d) = T}The condition (?) can be equivalently written: Pr ⊆ C implies c ∈ C.That is, C is Φ-closed, hence I(Φ) ⊆ C.
RemarkIf Pr = ∅, then (?) is equivalent to P(c) = T
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 13 / 106
Particular case: arithmetic induction
TheoremP predicate on natural numbers s.t.
P(0) = Tfor all n ∈ N, P(n) = T implies P(n + 1) = T
Then P(n) = T for all n ∈ N.
Proof.N can be seen as the set inductively defined by:
0 ∈ Nif n ∈ N then n + 1 ∈ N.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 14 / 106
Particular case: complete arithmetic induction
TheoremP predicate on natural numbers s.t.
P(0) = Tfor all n ∈ N, P(m) = T for all m < n implies P(n) = T
Then P(n) = T for all n ∈ N.
Proof.N can be seen as the set inductively defined by:
0 ∈ Nif m ∈ N for all m < n then n ∈ N.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 15 / 106
Particular case: structural induction
TheoremΣ signature, P predicate on Σ-terms s.t.
for all op ∈ Σn, P(t1) = T , . . . ,P(tn) = T implies P(op(t1, . . . , tn)) = T
Then P(t) = T for all t term over Σ.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 16 / 106
Multiple inference definitions (sketch)all previous definitions and results can be generalized to familiesa family of sets A indexed over S (S-family of sets) is a function whichassociates to each s ∈ S a set As
also written {As}s∈S
in a multiple inference system a rule has shape{Pr s}s∈S
c : sI(Φ) is an S-family of setsexamples: definitions of mutually recursive functions, general form ofsyntax (many syntactic categories = indexes, many-sorted signature)multiple induction principle: Φ multiple inference system, I(Φ) ⊆ U ,{Ps}s∈S family of predicates s.t. Ps : Us → {T ,F}
If for all{Pr s}s∈S
c : s∈ Φ
(?) (Ps(d) = T ∀d ∈ Pr s,∀s ∈ S) implies Ps(c) = T
then Ps(d) = T ∀d ∈ I(Φ),∀s ∈ S
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 17 / 106
Inductive definitions as fixed points
given f : A→ A and a ∈ A, a is a fixed point of f iff f (a) = agiven f : ℘(U)→ ℘(U) and X ⊆ U , X is a pre-fixed point of f (X isf -closed) iff f (X ) ⊆ XX is a least pre-fixed point of f iff f (Y ) ⊆ Y implies X ⊆ Yequivalently, X is the intersection of pre-fixed pointsf is monotone if X ⊆ Y implies f (X ) ⊆ f (Y )
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 18 / 106
TheoremGiven Φ an inference system with universe U , set fΦ : ℘(U)→ ℘(U) defined by:
for each X ⊆ U , fΦ(X ) = {c | Prc∈ Φ,Pr ⊆ X}
Then, fΦ is monotone and I(Φ) is the least pre-fixed point of fΦ(X ).
TheoremGiven f : ℘(U)→ ℘(U) monotone, set Φf defined by:
Φf = {Prc| Pr ⊆ U , c ∈ f (Pr)}
Then, I(Φf ) is the least pre-fixed point of f .
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 19 / 106
Part 2Small-step and big-step semantics
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 20 / 106
Small-step semantics
abstract model of program executionabstract machine:
I states s ∈ SI s → s′ reduction relationI if deterministic, a (partial) function
calculus: states are language terms t ∈ TI values v ∈ Val ⊆ TI a term t is a normal form if 6 ∃t ′.t → t ′ (shortly t 6→)
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 21 / 106
Introductory example: calculus E
boolean and natural expressions
t ::= true | false | if t then t1 else t2 | succ t| pred t | 0 | iszero t
v ::= true | false | nn ::= 0 | succ n
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 22 / 106
Reduction rules
Inductive definition of t → t ′
(IFTRUE)if true then t1 else t2 → t1
(IFFALSE)if false then t1 else t2 → t2
(IF)t → t ′
if t then t1 else t2 → if t ′ then t1 else t2
computational rules, congruence (propagation) rules
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 23 / 106
Reduction rules
(SUCC)t → t ′
succ t → succ t ′
(PRED)t → t ′
pred t → pred t ′(PREDZERO)
pred 0→ 0
(PREDSUCC)pred succ n→ n
(ISZEROZERO)iszero 0→ true
(ISZEROSUCC)iszero succ n→ false
(ISZERO)t → t ′
iszero t → iszero t ′
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 24 / 106
Example of reduction with proof trees
(IF)
(ISZERO)
(PREDSUCC)pred succ 0 → 0
iszero pred succ 0 → iszero 0
if iszero pred succ 0 then 0 else succ 0 → if iszero 0 then 0 else succ 0
(IF)
(ISZEROZERO)iszero 0 → true
if iszero 0 then 0 else succ 0 → if true then 0 else succ 0
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 25 / 106
Properties of E
any value is a normal formI the converse does not hold, e.g., succ trueI stuck terms are normal forms but not values
reduction is deterministic, that is, for all t there exists at most one t ′ s.t.t → t ′ (exercise)reduction is terminating, that is, any reduction sequence is finitehence, any term has a unique normal form
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 26 / 106
Big-step semantics
Inductive definition of t ⇓ v
(BIG-VAL)v ⇓ v
(BIG-IFTRUE)t ⇓ true t1 ⇓ v
if t then t1 else t2 ⇓ v(BIG-IFFALSE)
t ⇓ false t2 ⇓ vif t then t1 else t2 ⇓ v
(BIG-SUCC)t ⇓ n
succ t ⇓ succ n
(BIG-PREDZERO)t ⇓ 0
pred t ⇓ 0(BIG-PREDSUCC)
t ⇓ succ npred t ⇓ n
(BIG-ISZEROZERO)t ⇓ 0
iszero t ⇓ true(BIG-ISZEROSUCC)
t ⇓ succ niszero t ⇓ false
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 27 / 106
Proof of equivalence
t ⇓ v ⇒ t →? vBy induction on the definition of ⇓, that is:
for each (meta)rule defining ⇓, we prove that, if the property holds forthe premises, then it holds for the consequence
(BIG-VAL) Trivially v →? v (in zero steps).(BIG-IFTRUE) We have to prove that if t then t1 else t2 →? v . By inductive
hypothesis, t →? true. Then, by applying (IF) as many timesas the number of steps in t →? true, we get:
if t then t1 else t2 →? if true then t1 else t2
Now, by applying (IFTRUE), we getif true then t1 else t2 →? t1
and we conclude, since by inductive hypothesis t1 →? v .
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 28 / 106
Proof of equivalence
t →? v ⇒ t ⇓ vBy arithmetic induction on the length of the reduction sequence.
t →0 v Then t coincides with v , and we get the thesis.t →n+1 v Then t → t ′ →n v . By inductive hypothesis, t ′ ⇓ v . We prove, by
induction on the definition of→, that t → t ′ and t ′ ⇓ v implyt ⇓ v .
(IFTRUE) We must prove that t1 ⇓ v impliesif true then t1 else t2 ⇓ v . We get the thesisby applying rules (BIG-VAL) and (BIG-IFTRUE).
(IF) We must prove that if t ′ then t1 else t2 ⇓ vimplies if t then t1 else t2 ⇓ v . We derivedif t ′ then t1 else t2 ⇓ v by applying(BIG-IFTRUE) or (BIG-IFFALSE). Consider, e.g,the first case. Then, we know that premisest ′ ⇓ true and t1 ⇓ v hold. From the first premiseand t → t ′, by inductive hypothesis, we gett ⇓ true. By applying (BIG-IFTRUE) withpremises t ⇓ true e t1 ⇓ v we get the thesis.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 29 / 106
Lambda-calculus
introduced by Alonzo Church in the 1930s as part of an investigation intothe foundations of mathematicsTuring-complete formalism, can be considered “the smallestprogramming language”hence, studied as paradigmatic model of programming languages, whichcan all be encodedfunctional languages are more directly based on it
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 30 / 106
Basic idea
calculus of functionsbasic constructs: function definition and applicationin function definition, the “name” is not relevant: f (x) = x + 3 andg(x) = x + 3 define the same function, also sometimes denoted byx 7→ x + 3in the lambda-calculus we write λx.x + 3, or, by using the operators of E :
λx.succ succ succ x
meta-level abbreviation add3 = λx.succ succ succ x
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 31 / 106
Application
(λx.succ succ succ x)succ 0
(λx.succ succ succ x)succ 0→ succ succ succ succ 0
g = λf.f (f (succ 0))g add3 = (λf.f (f succ 0)) λx.succ succ succ x
→ (λx.succ succ succ x)((λx.succ succ succ x) succ 0)→ (λx.succ succ succ x) succ succ succ succ 0→ succ succ succ succ succ succ succ 0
double = λf.λy.f (fy)double add3 0 = (λf.λy.f (fy))(λx.succ succ succ x)0
→ (λy.(λx.succ succ succ x) ((λx.succ succ succ x)y))0→ (λx.succ succ succ x) ((λx.succ succ succ x)0)→ (λx.succ succ succ x) (succ succ succ 0)→ succ succ succ succ succ succ 0
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 32 / 106
Syntax
t ::= x | λx .t | t1 t2x ::= x | y | f | . . .
ConventionsI t1 t2 t3 = (t1 t2) t3I λx .t1t2 = λx .(t1 t2)
Binding, bound, free variablesλx.λy.x y zλx.(λy.z y) y
Exercise: formally define the set FV (t) of the free variables of t , anddim(t) the dimension of t , and prove that, for all t , | FV (t) |≤ dim(t)
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 33 / 106
Small step reduction rules
v ::= λx .t
(APPABSv )(λx .t) v → t [v/x ]
(APP1)t1 → t ′1
t1 t2 → t ′1 t2(APP2)
t2 → t ′2v t2 → v t ′2
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 34 / 106
Call-by-value strategy
corresponds to what usually happens in programming languages(APPABSv ) is a restricted version of β-rule:
(APPABS)(λx .t1) t2 → t1[t2/x ]
t1[t2/x ] is the term obtained by replacing all free occurrences of x in t1 byt2
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 35 / 106
Other strategies
(λx .t1) t2 is a redexfull-beta reduction (any redex can be reduced in a non-deterministic way)normal order (leftmost outermost redex)call-by-name (as above, but no reduction inside a lambda-abstraction)call-by-value versus call-by-name: e.g, in (λx .0) t , evaluation of t isuseless, and can even lead to non terminationHaskell uses an optimized version called call-by-need (the argument isevaluated only once)call-by-name versus call-by-need: e.g., consider (λx .x + x) tcall-by-value strategy is strict (eager), call-by-name and call-by-needstrategies are lazyexercise: formalize full-beta-reduction and call-by-name strategies
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 36 / 106
Consider id (id λz.id z) with id = λx.x
1 id (id λz.id z)
2 id (id λz.id z)
3 id (id λz.id z)
call-by-value reductionid (id λz.id z)→ id λz.id z→ λz.id z
(another) full-beta-reductionid (id λz.id z)→ id λz.id z→ λz.id z→ λz.z
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 37 / 106
Which properties hold for the lambda-calculus?
any value is a normal formI the converse does not hold, e.g., x
the call by value strategy is deterministic, that is, for all t there exists atmost one t ′ s.t. t → t ′ (exercise)reduction is non terminating, that is, there are infinite reductionsequences
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 38 / 106
Big-step semantics
(BIG-LAMBDA)λx .t ⇓ λx .t
(BIG-APP)t1 ⇓ λx .t t2 ⇓ v ′ t [v ′/x ] ⇓ v
t1 t2 ⇓ v
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 39 / 106
Part 3Type systems
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 40 / 106
What is a type system?
aim: define a subset of the language terms, the well-typed terms, whoseexecution cannot get stuckthis is obtained by classifying terms by different typeslanguage operators are applied coherently with such types
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 41 / 106
Introductory example: type system for E
T ::= Bool | Nat
(T-TRUE)true : Bool
(T-FALSE)false : Bool
(T-IF)t : Bool t1 : T t2 : Tif t then t1 else t2 : T
(T-ZERO)0 : Nat
(T-SUCC)t : Nat
succ t : Nat
(T-PRED)t : Nat
pred t : Nat(T-ISZERO)
t : Nat
iszero t : Bool
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 42 / 106
Example of proof tree
(T-IF)
(T-ISZERO)
(T-ZERO)0 : Nat
iszero 0 : Bool(T-ZERO)
0 : Nat(T-PRED)
(T-ZERO)0 : Nat
pred 0 : Natif iszero 0 then 0 else pred 0 : Nat
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 43 / 106
these metarules inductively define a relation t : Twe can prove by structural induction that this relation is a partial function,that is, each term has at most one type (not always true, e.g., inlanguages with subtyping)the type system gives a conservative (“pessimistic”) approximation of theexecution, that is:well-typed programs do not get stuck, but the converse does not hold,e.g.,
if true then 0 else false
Theorem (Soundness)If t : T and t →? t ′, then t ′ is not stuck (that is, t ′ is a value or t ′ →)
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 44 / 106
soundness is usually proved by:
Theorem (Progress)If t : T then t is not stuck (that is, t is a value or t →)
Theorem (Subject Reduction)If t : T and t → t ′ then t ′ : T
in general the type could be not exactly the same, but, e.g., a subtype
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 45 / 106
Progress+Subject reduction⇒ Soundness
Proof: By arithmetic induction on the length of the reductiont →0 t ′ Then t coincides with t ′, and the thesis follows from Progress.
t →n+1 t ′ Then t → t ′′ →n t ′. From Subject Reduction we have that t ′′ : T ,hence by inductive hypothesis we get the thesis.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 46 / 106
Inversion Lemma
For each kind of well-typed term, we state what we know about its type andthe types of the subterms.
Lemma (Inversion)1 If true : T then T = Bool.2 If false : T then T = Bool.3 If if t then t1 else t2 : T then t : Bool, t1 : T , and t2 : T .4 If 0 : T then T = Nat.5 If succ t : T then T = Nat, t : Nat.6 If pred t : T then T = Nat, t : Nat.7 If iszero t : T then T = Bool, t : Nat.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 47 / 106
Canonical Forms Lemma
For each type, we state which are the values of this type.
Lemma (Canonical Forms)1 If v is a value of type Bool then v = true or v = false.2 If v is a value of type Nat then v is of shape n, with
n ::= 0 | succ n
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 48 / 106
Theorem (Progress)If t : T then t ′ is not stuck (that is, t is a value or t →).
ProofBy induction on the definition of t : T (that is, ...). We show some cases:
(T-TRUE), (T-FALSE), (T-ZERO) Immediate, since t is a value.(T-IF) We have if t then t1 else t2 : T , hence t : Bool, t1 : T and
t2 : T by the Inversion lemma.By inductive hypothesis on t , either t is a value, or t →.
If t is a value, then by the Canonical Forms lemma eithert = true or t = false, hence we can apply either(IFTRUE) or (IFFALSE).If t → t ′, then by rule (IF) we derive thatif t then t1 else t2 → if t ′ then t1 else t2.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 49 / 106
Theorem (Subject Reduction)If t : T and t → t ′ then t ′ : T
ProofBy induction on the definition of t → t ′ (that is, ...) We show some cases.
(IF-TRUE) We have if true then t1 else t2 → t1. From the hypothesisif true then t1 else t2 : T and the Inversion lemma we havet1 : T , hence the thesis.
(IF) We have if t then t1 else t2 → if t ′ then t1 else t2 et → t ′. From the hypothesis if t then t1 else t2 : T and theInversion lemma we have t : Bool, t1 : T e t2 : T . By inductivehypothesis on t → t ′, and t : Bool, we get t ′ : Bool, hence by(T-IF) we derive if t ′ then t1 else t2 : T .
(SUCC) We have succ t → succ t ′ and t → t ′. From the hypothesissucc t : T and the Inversion lemma we have succ t : Nat et : Nat. By inductive hypothesis on t → t ′, and t : Nat, we gett ′ : Nat, hence by (T-SUCC) we derive succ t ′ : Nat.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 50 / 106
Simply-typed lambda-calculus (+ E)
explicitly typed approach (Church-style):I add type annotations when declaring variables
t ::= x | λx : T .t | t1 t2 | true | false| if t then t1 else t2 | . . .
v ::= λx : T .t | true | false | . . .T ::= Bool | Nat | T1 → T2
I there is an identity function for each type, e.g., λx : Bool.x, λx : Nat.x, . . .
alternative approach:I implicitly typed (Curry-style)
t ::= x | λx .t | t1 t2 | true | false| if t then t1 else t2 | . . .
v ::= λx .t | true | false | . . .T ::= Bool | Nat | T1 → T2 | α | (∀α)T
I polymorphism: only one function λx.xI most general type (∀α)α→ α
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 51 / 106
typing relation Γ ` t : T with Γ type context, needed to type free variablesΓ is a partial function from variables to typesΓ[T/x ] denotes the function which returns T on x , is equal to Γ otherwise
(T-TRUE)Γ ` true : Bool
(T-FALSE)Γ ` false : Bool
(T-IF)Γ ` t : Bool Γ ` t1 : T Γ ` t2 : T
Γ ` if t then t1 else t2 : T(T-VAR)
Γ ` x : TΓ(x) = T
(T-ABS)Γ[T1/x ] ` t : T2
Γ ` λx : T1.t : T1 → T2(T-APP)
Γ ` t1 : T2 → T Γ ` t2 : T2
Γ ` t1 t2 : T
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 52 / 106
Soundness of the type system with simple types
Theorem (Soundness)If t : T and t →? t ′, then t ′ is not stuck (that is, t ′ is a value or t ′ →)
Theorem (Progress)If t : T , then t is not stuck (that is, t ′ is a value or t ′ →)
Theorem (Subject reduction)If Γ ` t : T and t → t ′ then Γ ` t ′ : T .
progress (and soundness) only holds for closed termsthe proof is structured as before
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 53 / 106
Lemma (Inversion)1 If Γ ` true : T then T = Bool.2 If Γ ` false : T then T = Bool.3 If Γ ` if t then t1 else t2 : T then Γ ` t : Bool, Γ ` t1 : T e Γ ` t2 : T .4 If Γ ` x : T then x : T ∈ Γ.5 If Γ ` λx : T1.t : T then T = T1 → T2 e Γ[T1/x ] ` t : T2 for some T2.6 If Γ ` t1 t2 : T then Γ ` t1 : T2 → T e Γ ` t2 : T2 for some T2.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 54 / 106
Lemma (Canonical Forms)1 If v is a value of type Bool, then v is true or v is false.2 If v is a value of type T1 → T2, then v is of shape λx : T1.t .
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 55 / 106
Theorem (Progress)If t : T , then t is not stuck (that is, t ′ is a value or t ′ →)
ProofBy induction on t : T .
(T-VAR) Empty since Γ = ∅.(T-ABS) Trivial since t is a value.(T-APP) We have t1 t2 : T . From the inversion lemma t1 : T2 → T and
t2 : T2 for some T2. By inductive hypothesis either t1 is a valueor t1 →, and analogously for t2.
If t1 →, then we can apply rule (APP1).If t1 is a value and t2 →, then we can apply rule (APP2).If both t1 and t2 are values, then, from the Canonical Formslemma, t1 = λx : T2.t , hence we can apply rule(APPABSv ).
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 56 / 106
Theorem (Subject reduction)If Γ ` t : T and t → t ′ then Γ ` t ′ : T .
ProofBy induction on t → t ′.
(APP1) We have t1 t2 → t ′1 t2. From the hypothesis Γ ` t1 t2 : T and theInversion lemma, we have Γ ` t1 : T2 → T and Γ ` t2 : T2 forsome T2. If the applied rule is (APP1) or (APP2), then we simplyapply the inductive hypothesis (to t1 → t ′1 or t2 → t ′2). If theapplied rule is (APPABSv ), then
t1 = λx : T2.t ,t2 e un valore v ,t1 t2 → t [v/x ]
From the hypothesis Γ ` λx : T2.t : T2 → T and the Inversionlemma (point 5) we have Γ[T2/x ] ` t : T . To conclude, we needto apply the following lemma.
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 57 / 106
Lemma (Substitution)Types are preserved by substitution, formally:
If Γ[T1/x ] ` t : T e Γ ` t ′ : T1, then Γ ` t [t ′/x ] : T .
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 58 / 106
Part 3Functional programming in Haskell
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 59 / 106
Functional programmingearly functional flavored languages: LISP (John McCarthy, late 1950s), then IPLand APL1977: John Backus Turing Award lecture “Can Programming Be Liberated Fromthe von Neumann Style? A Functional Style and its Algebra of Programs.”1970: ML (Robin Milner, University of Edinburgh)several ML dialects, most common now Objective Caml and Standard ML1970s: Scheme (Lisp dialect) brought functional programming to the widerprogramming-languages communityfollowing Miranda (David Turner, 1985), interest in lazy functional languagesgrew: by 1987, more than a dozenat FPCA ’87 in Portland, consensus that a committee should define an openstandard for such languagesfirst version defined in 1990Haskell 98: stable, minimal, portable version of the language with standard libraryfor teaching, and as a base for future extensionsin January 2003 revised versionGlasgow Haskell Compiler (GHC) current de facto standard implementationfrom 2006, ongoing process of defining a successor to the Haskell 98 standard(last revision published in July 2010)
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 60 / 106
Basics: lambda-expressions
lambda-calculus forms the basis, as in almost all functional programminglanguages todayexpressions which denote functions: \ x -> x+1
function application (\ x -> x+1) 2
syntactic conventions as in the lambda calculusdeclarations of functions:
inc = \x -> x+1inc x = x + 1
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 62 / 106
Basics: types and declarations
each value has a type, the following are type signature declarations
5 :: Integer’a’ :: Char\x -> x + 1 :: Integer -> Integer[1,2,3] :: [Integer](’b’,4) :: (Char,Integer)
the type system is sound, and infers type signaturestypes universally quantified over all types, e.g.,∀a [a] is the type of all homogeneous listsquantifier is omitted
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 64 / 106
Functions
Higher-order functions
compose (f, g) x = f (g x)compose (f, g) = \x -> f (g x)compose = \(f, g) -> \x -> f (g x)
double f x = f (f x)
*Main> compose (inc, inc) 13
*Main> double inc 57
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 66 / 106
Functions
Curried functions
sum:: (Integer, Integer) -> Integersum (x,y) = x + ysum(1,2)add:: Integer -> Integer -> Integeradd x y = x + y
*Main> add 1 23compose f g x = f(g x)
Partial application
inc = add 1
*Main> :type compose inc inccompose inc inc :: Integer -> Integer
*Main> :type compose inccompose inc :: (t -> Integer) -> t -> Integer
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 68 / 106
given a functionf : A×B → C, its curried version f : A→ B → C is defined by: for all a ∈ A,
f (a) : B → C,for all b ∈ B, f (a)(b) = f (a,b)
conversely, given a function g : A→ B → C, its uncurried versiong : A× B → C is defined by: for all a ∈ A, b ∈ B,
g(a,b) = g(a)(b)
curry and uncurry operators can be defined in Haskell:
curry f = \a -> \b -> f (a, b)uncurry g = \(a, b) -> g a b
*Main> :type curry sumcurry sum :: Integer -> Integer -> Integer
*Main> :type currycurry :: ((a, b) -> c) -> a -> b -> c
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 70 / 106
Polymorphism
the definition of the identity function f (x) = x makes sense independentlyfrom the nature of the argumentin languages allowing polymorphism it is possible to write suchdefinitions: \x -> x
one definition applicable to arguments of different typesdifferent from overloading: same name for different definitions
*Main> :type (\x -> x)(\x -> x) :: t -> t
*Main> :type composecompose :: (t1 -> t2) -> (t -> t1) -> t -> t2first(x,y) = x
*Main> :type (first)(first) :: (t, t1) -> t
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 72 / 106
Polymorphism
some types are more general than others, e.g., [a] -> a is more generalthan [Integer] -> Integer
any expression has a most general or principal typethe principal type represents all the different types a function can assumethe type of compose in the expression compose inc inc is
(Integer->Integer) -> (Integer->Integer)->Integer->Integer
obtained by instantiating the type variableseach (well-typed) Haskell expression has a unique principal (mostgeneral) typetype inference: the programmer is not required to insert type annotations
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 74 / 106
Functions
infix operators are just functions and can be defined:
(++):: [a] -> [a] -> [a][]++xs = xs(x:xs)++ys = x:(xs++ys)
(.) :: (b -> c) -> (a -> b) -> (a -> c)f.g = \x -> f(g x)
partial applications of infix operators are called sections
(x+) ≡ \y -> x + y(+y) ≡ \x -> x + y(+) ≡ \x y -> x + y
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 76 / 106
Pattern matchinggeneral formf p1 = e1
...f pn = en
pattern = expression with free variables, describing a possible shape ofthe argumentpatterns are considered in the given order, hence each pattern behaveslike a filter for the following (unless irrefutable)examplenegate True = Falsenegate False = True
ornegate True = Falsenegate x = True
or using a wild-cardnegate True = Falsenegate _ = True
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 78 / 106
an exception is raised if a function is invoked on an argument which doesnot match any pattern:
*Main> let f 0 = 0 in f 1
*** Exception: <interactive>:1:4-10: Non-exhaustivepatterns in function f
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 80 / 106
Another example
Implication
implies True False = Falseimplies _ _ = True
a variable cannot be repeated, e.g.:
*Main> let f x x = 0 in f 0 0<interactive>:1:6:
Conflicting definitions for ‘x’Bound at: <interactive>:1:6
<interactive>:1:8In the definition of ‘f’
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 82 / 106
Lists
[1,2,3] is a shorthand for 1:2:3:[]example of function defined by pattern-matching:
length [] = 0length (_:xs) = 1 + length xs
is a polymorphic function
length:: [a] -> Integerlength [1,2,3]length [’a’,’b’,’c’]length [[1],[2,3],[4,5,6]]
other polymorphic functions:
head:: [a] -> ahead (x:_) = xtail::[a]->[a]tail (_:xs) = xs
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 84 / 106
Polymorphic functions on lists
map :: (t -> a) -> [t] -> [a]map f [] = []map f (x:xs) = f x : map f xs
itlist f a [] = aitlist f a (x:xs) = itlist f (f a x) xs
sumlist = itlist (+) 0flatten = itlist (++) []
filter p [] = []filter p (x:xs) = (if p x then [x] else [])++(filter p xs)
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 86 / 106
List comprehension
filter p xs = [x | x <- xs, p x]
quicksort [] = []quicksort (x:xs) =quicksort [y|y<-xs,y<x]++[x]++ quicksort [y|y<-xs,y>=x]
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 88 / 106
User-defined types
data Bool = False | True
Bool is a type constructor, True and False are (data) constructors
data Colour = Red | Green | Blue | Indigo | Violetdata Point a = Point a a
(disjoint) union or sum types, polymorphic tuple typethe type constructor Point has type a -> a -> Point a, hence, e.g.:
Point 1 2 :: Point IntegerPoint ’a’ ’b’ :: Point CharPoint True False :: Point Bool
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 90 / 106
Recursive types
data BTree a = Empty | Node (a, BTree a, BTree a)
*Main> :type NodeNode :: (a, BTree a, BTree a) -> BTree a
insert :: Ord a => a -> BTree a -> BTree ainsert a Empty = Node(a, Empty, Empty)insert a n@(Node(b,l,r)) =if (a<b) then Node(b, insert a l, r)else if (a>b) then Node(b,l, insert a r)else n
consBTree :: Ord a => [a] -> BTree aconsBTree = itlist (\t -> \a -> insert a t) Empty
inorder Empty = []inorder (Node(a,l,r)) = (inorder l)++[a]++(inorder r)
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 92 / 106
Functions are non-strict
Haskell adopts a lazy evaluation strategy: call by need
Prelude> let bot = bot in (\x -> 0) bot0Prelude> let x = 1/0 in (\y -> 15) x15
advantage: computationally expensive values may be passed as argumentsintuition: read declarations as definitions rather than assignmentsother advantage: order of declarations does not matter
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 94 / 106
Infinite data structures
data constructors are non-strict toothis allows the definition of infinite data structures
ones = 1 : onesnumFrom n = n : numFrom(n+1)squaresFrom n = map (ˆ2) (numFrom n)take _ [] = []take 0 _ = []take n (x:xs) = x:take(n-1) xs
*Main> take 5 (squaresFrom 0)[0,1,4,9,16]
infinite terms can be represented as graphs
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 96 / 106
Another example
Fibonacci numbersfib0 = 1fib1 = 1fibi+2 = fibi + fibi+1
zip (x:xs) (y:ys) = (x,y) :: zip xs yszip _ _ = []
fib = 1: 1: [a+b | (a,b) <- zip fib (tail fib)]
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 98 / 106
Type classes
Example: equality
isin _ [] = Falseisin x (y:ys) = x==y || isin x ys
type of isin should be a -> [a] -> Bool
but, we do not expect equality to be defined for all typesmoreover, we expect the definition of equality to be different for each typethat is, == should be an overloaded function
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 100 / 106
Type classes
Type class declarationA type class declares a collection of overloaded functions:
class Eq a where(==) :: a -> a -> Bool
The constraint that a type a must be an instance of the class Eq is writtenEq a, and is called a context
*Main> :type (==)(==) :: (Eq a) => a -> a -> Bool
*Main> :type isinisin :: (Eq a) => a -> [a] -> Bool
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 102 / 106
Instance declaration
instance (Eq a) => Eq (BTree a) whereEmpty == Empty = TrueNode(a,l1,r1) == Node(b,l2,r2) = (a==b)&&(l1==l2)&&(r1==r2)_ == _ = False
*Main> Node(1,Empty,Empty) == Node(1,Empty,Empty)True
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 104 / 106
Deriving
the following declaration
data BTree a = Empty | Node (a, BTree a, BTree a)deriving (Eq, Show)
automatically generates an appropriate instance declaration for Eq andShow (the type class which declares a function for converting to String)this feature is only supported for the Eq, Show and Ord predefined typeclassesnote that String is just an alias for [Char]
Ancona, Lagorio, Zucca (Univ. of Genova) Declarative Programming and (Co)Induction DISI, June 13-17, 2011 106 / 106